Blame view

net/netfilter/nf_conntrack_proto_tcp.c 44.4 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
3
4
5
6
  /* (C) 1999-2001 Paul `Rusty' Russell
   * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
7
   */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
8
  #include <linux/types.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
9
  #include <linux/timer.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
10
11
12
13
14
15
16
  #include <linux/module.h>
  #include <linux/in.h>
  #include <linux/tcp.h>
  #include <linux/spinlock.h>
  #include <linux/skbuff.h>
  #include <linux/ipv6.h>
  #include <net/ip6_checksum.h>
534f81a50   Mark H. Weaver   netfilter: nf_con...
17
  #include <asm/unaligned.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
18
19
20
21
22
23
24
  
  #include <net/tcp.h>
  
  #include <linux/netfilter.h>
  #include <linux/netfilter_ipv4.h>
  #include <linux/netfilter_ipv6.h>
  #include <net/netfilter/nf_conntrack.h>
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
25
  #include <net/netfilter/nf_conntrack_l4proto.h>
f61801218   Martin Josefsson   [NETFILTER]: nf_c...
26
  #include <net/netfilter/nf_conntrack_ecache.h>
f01ffbd6e   Patrick McHardy   [NETFILTER]: nf_l...
27
  #include <net/netfilter/nf_log.h>
9d2493f88   Christoph Paasch   netfilter: remove...
28
29
  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
30

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
31
32
  /* "Be conservative in what you do,
      be liberal in what you accept from others."
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
33
      If it's non-zero, we mark only out of window RST segments as INVALID. */
3aef0fd91   Patrick McHardy   [NETFILTER]: nf_c...
34
  static int nf_ct_tcp_be_liberal __read_mostly = 0;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
35

a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
36
  /* If it is set to zero, we disable picking up already established
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
37
     connections. */
3aef0fd91   Patrick McHardy   [NETFILTER]: nf_c...
38
  static int nf_ct_tcp_loose __read_mostly = 1;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
39

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
40
41
  /* Max number of the retransmitted packets without receiving an (acceptable)
     ACK from the destination. If this number is reached, a shorter timer
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
42
     will be started. */
3aef0fd91   Patrick McHardy   [NETFILTER]: nf_c...
43
  static int nf_ct_tcp_max_retrans __read_mostly = 3;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
44
45
46
  
    /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
       closely.  They're more complex. --RR */
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
47
  static const char *const tcp_conntrack_names[] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
48
49
50
51
52
53
54
55
56
  	"NONE",
  	"SYN_SENT",
  	"SYN_RECV",
  	"ESTABLISHED",
  	"FIN_WAIT",
  	"CLOSE_WAIT",
  	"LAST_ACK",
  	"TIME_WAIT",
  	"CLOSE",
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
57
  	"SYN_SENT2",
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
58
  };
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
59

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
60
61
62
63
  #define SECS * HZ
  #define MINS * 60 SECS
  #define HOURS * 60 MINS
  #define DAYS * 24 HOURS
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
64
  /* RFC1122 says the R2 limit should be at least 100 seconds.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
65
     Linux uses 15 packets as limit, which corresponds
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
66
     to ~13-30min depending on RTO. */
ae375044d   Patrick McHardy   netfilter: nf_con...
67
68
  static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly    =   5 MINS;
  static unsigned int nf_ct_tcp_timeout_unacknowledged __read_mostly =   5 MINS;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
69

2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
70
71
72
73
74
75
76
77
78
  static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
  	[TCP_CONNTRACK_SYN_SENT]	= 2 MINS,
  	[TCP_CONNTRACK_SYN_RECV]	= 60 SECS,
  	[TCP_CONNTRACK_ESTABLISHED]	= 5 DAYS,
  	[TCP_CONNTRACK_FIN_WAIT]	= 2 MINS,
  	[TCP_CONNTRACK_CLOSE_WAIT]	= 60 SECS,
  	[TCP_CONNTRACK_LAST_ACK]	= 30 SECS,
  	[TCP_CONNTRACK_TIME_WAIT]	= 2 MINS,
  	[TCP_CONNTRACK_CLOSE]		= 10 SECS,
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
79
  	[TCP_CONNTRACK_SYN_SENT2]	= 2 MINS,
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
80
  };
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
81

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
82
83
84
85
86
87
88
89
90
  #define sNO TCP_CONNTRACK_NONE
  #define sSS TCP_CONNTRACK_SYN_SENT
  #define sSR TCP_CONNTRACK_SYN_RECV
  #define sES TCP_CONNTRACK_ESTABLISHED
  #define sFW TCP_CONNTRACK_FIN_WAIT
  #define sCW TCP_CONNTRACK_CLOSE_WAIT
  #define sLA TCP_CONNTRACK_LAST_ACK
  #define sTW TCP_CONNTRACK_TIME_WAIT
  #define sCL TCP_CONNTRACK_CLOSE
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
91
  #define sS2 TCP_CONNTRACK_SYN_SENT2
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
92
93
94
95
96
97
98
99
100
101
102
103
  #define sIV TCP_CONNTRACK_MAX
  #define sIG TCP_CONNTRACK_IGNORE
  
  /* What TCP flags are set from RST/SYN/FIN/ACK. */
  enum tcp_bit_set {
  	TCP_SYN_SET,
  	TCP_SYNACK_SET,
  	TCP_FIN_SET,
  	TCP_ACK_SET,
  	TCP_RST_SET,
  	TCP_NONE_SET,
  };
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
104

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
105
106
107
108
109
  /*
   * The TCP state transition table needs a few words...
   *
   * We are the man in the middle. All the packets go through us
   * but might get lost in transit to the destination.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
110
   * It is assumed that the destinations can't receive segments
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
111
112
113
114
115
116
117
118
119
   * we haven't seen.
   *
   * The checked segment is in window, but our windows are *not*
   * equivalent with the ones of the sender/receiver. We always
   * try to guess the state of the current sender.
   *
   * The meaning of the states are:
   *
   * NONE:	initial state
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
120
   * SYN_SENT:	SYN-only packet seen
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
121
   * SYN_SENT2:	SYN-only packet seen from reply dir, simultaneous open
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
122
123
124
   * SYN_RECV:	SYN-ACK packet seen
   * ESTABLISHED:	ACK packet seen
   * FIN_WAIT:	FIN packet seen
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
125
   * CLOSE_WAIT:	ACK seen (after FIN)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
126
127
   * LAST_ACK:	FIN seen (after FIN)
   * TIME_WAIT:	last ACK seen
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
128
   * CLOSE:	closed connection (RST)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
129
   *
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
130
   * Packets marked as IGNORED (sIG):
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
131
132
   *	if they may be either invalid or valid
   *	and the receiver may send back a connection
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
133
134
135
   *	closing RST or a SYN/ACK.
   *
   * Packets marked as INVALID (sIV):
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
136
   *	if we regard them as truly invalid packets
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
137
   */
a5e73c29d   Patrick McHardy   [NETFILTER]: nf_c...
138
  static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
139
140
  	{
  /* ORIGINAL */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
141
142
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*syn*/	   { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sS2 },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
143
144
145
  /*
   *	sNO -> sSS	Initialize a new connection
   *	sSS -> sSS	Retransmitted SYN
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
146
147
   *	sS2 -> sS2	Late retransmitted SYN
   *	sSR -> sIG
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
148
   *	sES -> sIG	Error: SYNs in window outside the SYN_SENT state
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
149
   *			are errors. Receiver will reply with RST
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
150
151
152
153
154
155
156
157
   *			and close the connection.
   *			Or we are not in sync and hold a dead connection.
   *	sFW -> sIG
   *	sCW -> sIG
   *	sLA -> sIG
   *	sTW -> sSS	Reopened connection (RFC 1122).
   *	sCL -> sSS
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
158
159
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*synack*/ { sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
160
  /*
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
161
162
163
164
165
166
167
168
169
170
171
172
173
   *	sNO -> sIV	Too late and no reason to do anything
   *	sSS -> sIV	Client can't send SYN and then SYN/ACK
   *	sS2 -> sSR	SYN/ACK sent to SYN2 in simultaneous open
   *	sSR -> sIG
   *	sES -> sIG	Error: SYNs in window outside the SYN_SENT state
   *			are errors. Receiver will reply with RST
   *			and close the connection.
   *			Or we are not in sync and hold a dead connection.
   *	sFW -> sIG
   *	sCW -> sIG
   *	sLA -> sIG
   *	sTW -> sIG
   *	sCL -> sIG
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
174
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
175
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
176
177
178
179
180
  /*fin*/    { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
  /*
   *	sNO -> sIV	Too late and no reason to do anything...
   *	sSS -> sIV	Client migth not send FIN in this state:
   *			we enforce waiting for a SYN/ACK reply first.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
181
   *	sS2 -> sIV
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
182
183
184
   *	sSR -> sFW	Close started.
   *	sES -> sFW
   *	sFW -> sLA	FIN seen in both directions, waiting for
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
185
   *			the last ACK.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
186
187
188
189
190
191
   *			Migth be a retransmitted FIN as well...
   *	sCW -> sLA
   *	sLA -> sLA	Retransmitted FIN. Remain in the same state.
   *	sTW -> sTW
   *	sCL -> sCL
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
192
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
193
194
195
196
  /*ack*/	   { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
  /*
   *	sNO -> sES	Assumed.
   *	sSS -> sIV	ACK is invalid: we haven't seen a SYN/ACK yet.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
197
   *	sS2 -> sIV
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
198
199
200
201
202
203
204
205
   *	sSR -> sES	Established state is reached.
   *	sES -> sES	:-)
   *	sFW -> sCW	Normal close request answered by ACK.
   *	sCW -> sCW
   *	sLA -> sTW	Last ACK detected.
   *	sTW -> sTW	Retransmitted last ACK. Remain in the same state.
   *	sCL -> sCL
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
206
207
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
208
209
210
211
  /*none*/   { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
  	},
  	{
  /* REPLY */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
212
213
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*syn*/	   { sIV, sS2, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sS2 },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
214
215
  /*
   *	sNO -> sIV	Never reached.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
216
217
218
219
   *	sSS -> sS2	Simultaneous open
   *	sS2 -> sS2	Retransmitted simultaneous SYN
   *	sSR -> sIV	Invalid SYN packets sent by the server
   *	sES -> sIV
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
220
221
222
223
224
225
   *	sFW -> sIV
   *	sCW -> sIV
   *	sLA -> sIV
   *	sTW -> sIV	Reopened connection, but server may not do it.
   *	sCL -> sIV
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
226
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
8a80c79a7   Pablo Neira Ayuso   netfilter: nf_ct_...
227
  /*synack*/ { sIV, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
228
229
  /*
   *	sSS -> sSR	Standard open.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
230
   *	sS2 -> sSR	Simultaneous open
8a80c79a7   Pablo Neira Ayuso   netfilter: nf_ct_...
231
   *	sSR -> sIG	Retransmitted SYN/ACK, ignore it.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
232
233
234
235
236
237
238
   *	sES -> sIG	Late retransmitted SYN/ACK?
   *	sFW -> sIG	Might be SYN/ACK answering ignored SYN
   *	sCW -> sIG
   *	sLA -> sIG
   *	sTW -> sIG
   *	sCL -> sIG
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
239
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
240
241
242
  /*fin*/    { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
  /*
   *	sSS -> sIV	Server might not send FIN in this state.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
243
   *	sS2 -> sIV
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
244
245
246
247
248
249
250
251
   *	sSR -> sFW	Close started.
   *	sES -> sFW
   *	sFW -> sLA	FIN seen in both directions.
   *	sCW -> sLA
   *	sLA -> sLA	Retransmitted FIN.
   *	sTW -> sTW
   *	sCL -> sCL
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
252
253
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*ack*/	   { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIG },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
254
  /*
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
255
   *	sSS -> sIG	Might be a half-open connection.
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
256
   *	sS2 -> sIG
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
257
258
259
260
261
262
263
264
   *	sSR -> sSR	Might answer late resent SYN.
   *	sES -> sES	:-)
   *	sFW -> sCW	Normal close request answered by ACK.
   *	sCW -> sCW
   *	sLA -> sTW	Last ACK detected.
   *	sTW -> sTW	Retransmitted last ACK.
   *	sCL -> sCL
   */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
265
266
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
  /*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
267
  /*none*/   { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
268
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
269
  };
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
270
271
  static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
  			     struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
272
  {
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
273
274
  	const struct tcphdr *hp;
  	struct tcphdr _hdr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
275
276
277
278
  
  	/* Actually only need first 8 bytes. */
  	hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
  	if (hp == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
279
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
280
281
282
  
  	tuple->src.u.tcp.port = hp->source;
  	tuple->dst.u.tcp.port = hp->dest;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
283
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
284
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
285
286
  static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
  			     const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
287
288
289
  {
  	tuple->src.u.tcp.port = orig->dst.u.tcp.port;
  	tuple->dst.u.tcp.port = orig->src.u.tcp.port;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
290
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
291
292
293
294
295
296
297
298
299
300
301
302
  }
  
  /* Print out the per-protocol part of the tuple. */
  static int tcp_print_tuple(struct seq_file *s,
  			   const struct nf_conntrack_tuple *tuple)
  {
  	return seq_printf(s, "sport=%hu dport=%hu ",
  			  ntohs(tuple->src.u.tcp.port),
  			  ntohs(tuple->dst.u.tcp.port));
  }
  
  /* Print out the private part of the conntrack. */
440f0d588   Patrick McHardy   netfilter: nf_con...
303
  static int tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
304
305
  {
  	enum tcp_conntrack state;
440f0d588   Patrick McHardy   netfilter: nf_con...
306
  	spin_lock_bh(&ct->lock);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
307
  	state = ct->proto.tcp.state;
440f0d588   Patrick McHardy   netfilter: nf_con...
308
  	spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  
  	return seq_printf(s, "%s ", tcp_conntrack_names[state]);
  }
  
  static unsigned int get_conntrack_index(const struct tcphdr *tcph)
  {
  	if (tcph->rst) return TCP_RST_SET;
  	else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
  	else if (tcph->fin) return TCP_FIN_SET;
  	else if (tcph->ack) return TCP_ACK_SET;
  	else return TCP_NONE_SET;
  }
  
  /* TCP connection tracking based on 'Real Stateful TCP Packet Filtering
     in IP Filter' by Guido van Rooij.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
324

631dd1a88   Justin P. Mattock   Update broken web...
325
326
     http://www.sane.nl/events/sane2000/papers.html
     http://www.darkart.com/mirrors/www.obfuscation.org/ipf/
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
327

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
328
329
330
331
     The boundaries and the conditions are changed according to RFC793:
     the packet must intersect the window (i.e. segments may be
     after the right or before the left edge) and thus receivers may ACK
     segments after the right edge of the window.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
332
  	td_maxend = max(sack + max(win,1)) seen in reply packets
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
333
334
335
336
  	td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
  	td_maxwin += seq + len - sender.td_maxend
  			if seq + len > sender.td_maxend
  	td_end    = max(seq + len) seen in sent packets
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
337

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
338
339
     I.   Upper bound for valid data:	seq <= sender.td_maxend
     II.  Lower bound for valid data:	seq + len >= sender.td_end - receiver.td_maxwin
84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
340
341
     III.	Upper bound for valid (s)ack:   sack <= receiver.td_end
     IV.	Lower bound for valid (s)ack:	sack >= receiver.td_end - MAXACKWINDOW
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
342

84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
343
344
     where sack is the highest right edge of sack block found in the packet
     or ack in the case of packet without SACK option.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
345

84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
346
     The upper bound limit for a valid (s)ack is not ignored -
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
347
     we doesn't have to deal with fragments.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
348
349
350
351
352
  */
  
  static inline __u32 segment_seq_plus_len(__u32 seq,
  					 size_t len,
  					 unsigned int dataoff,
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
353
  					 const struct tcphdr *tcph)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
354
355
356
357
358
359
  {
  	/* XXX Should I use payload length field in IP/IPv6 header ?
  	 * - YK */
  	return (seq + len - dataoff - tcph->doff*4
  		+ (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
  }
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
360

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
361
362
363
364
365
  /* Fixme: what about big packets? */
  #define MAXACKWINCONST			66000
  #define MAXACKWINDOW(sender)						\
  	((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin	\
  					      : MAXACKWINCONST)
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
366

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
367
368
369
370
371
  /*
   * Simplified tcp_parse_options routine from tcp_input.c
   */
  static void tcp_options(const struct sk_buff *skb,
  			unsigned int dataoff,
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
372
  			const struct tcphdr *tcph,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
373
374
375
  			struct ip_ct_tcp_state *state)
  {
  	unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
376
  	const unsigned char *ptr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
377
378
379
380
381
382
383
384
  	int length = (tcph->doff*4) - sizeof(struct tcphdr);
  
  	if (!length)
  		return;
  
  	ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
  				 length, buff);
  	BUG_ON(ptr == NULL);
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
385
  	state->td_scale =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  	state->flags = 0;
  
  	while (length > 0) {
  		int opcode=*ptr++;
  		int opsize;
  
  		switch (opcode) {
  		case TCPOPT_EOL:
  			return;
  		case TCPOPT_NOP:	/* Ref: RFC 793 section 3.1 */
  			length--;
  			continue;
  		default:
  			opsize=*ptr++;
  			if (opsize < 2) /* "silly options" */
  				return;
  			if (opsize > length)
4a5cc84ae   Jozsef Kadlecsik   netfilter: nf_ct_...
403
  				return;	/* don't parse partial options */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
404

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
405
  			if (opcode == TCPOPT_SACK_PERM
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
  			    && opsize == TCPOLEN_SACK_PERM)
  				state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
  			else if (opcode == TCPOPT_WINDOW
  				 && opsize == TCPOLEN_WINDOW) {
  				state->td_scale = *(u_int8_t *)ptr;
  
  				if (state->td_scale > 14) {
  					/* See RFC1323 */
  					state->td_scale = 14;
  				}
  				state->flags |=
  					IP_CT_TCP_FLAG_WINDOW_SCALE;
  			}
  			ptr += opsize - 2;
  			length -= opsize;
  		}
  	}
  }
  
  static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
426
                       const struct tcphdr *tcph, __u32 *sack)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
427
  {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
428
  	unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
429
  	const unsigned char *ptr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
430
431
432
433
434
435
436
437
438
439
440
  	int length = (tcph->doff*4) - sizeof(struct tcphdr);
  	__u32 tmp;
  
  	if (!length)
  		return;
  
  	ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
  				 length, buff);
  	BUG_ON(ptr == NULL);
  
  	/* Fast path for timestamp-only option */
bb9fc3735   Jozsef Kadlecsik   netfilter: nf_ct_...
441
  	if (length == TCPOLEN_TSTAMP_ALIGNED
8f05ce91c   YOSHIFUJI Hideaki   [NET] NETFILTER: ...
442
443
444
445
  	    && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
  				       | (TCPOPT_NOP << 16)
  				       | (TCPOPT_TIMESTAMP << 8)
  				       | TCPOLEN_TIMESTAMP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  		return;
  
  	while (length > 0) {
  		int opcode = *ptr++;
  		int opsize, i;
  
  		switch (opcode) {
  		case TCPOPT_EOL:
  			return;
  		case TCPOPT_NOP:	/* Ref: RFC 793 section 3.1 */
  			length--;
  			continue;
  		default:
  			opsize = *ptr++;
  			if (opsize < 2) /* "silly options" */
  				return;
  			if (opsize > length)
4a5cc84ae   Jozsef Kadlecsik   netfilter: nf_ct_...
463
  				return;	/* don't parse partial options */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
464

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
465
466
467
468
469
470
471
472
  			if (opcode == TCPOPT_SACK
  			    && opsize >= (TCPOLEN_SACK_BASE
  					  + TCPOLEN_SACK_PERBLOCK)
  			    && !((opsize - TCPOLEN_SACK_BASE)
  				 % TCPOLEN_SACK_PERBLOCK)) {
  				for (i = 0;
  				     i < (opsize - TCPOLEN_SACK_BASE);
  				     i += TCPOLEN_SACK_PERBLOCK) {
534f81a50   Mark H. Weaver   netfilter: nf_con...
473
  					tmp = get_unaligned_be32((__be32 *)(ptr+i)+1);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
474
475
476
477
478
479
480
481
482
483
484
  
  					if (after(tmp, *sack))
  						*sack = tmp;
  				}
  				return;
  			}
  			ptr += opsize - 2;
  			length -= opsize;
  		}
  	}
  }
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
485
486
487
488
489
490
491
492
493
494
495
496
497
498
  #ifdef CONFIG_NF_NAT_NEEDED
  static inline s16 nat_offset(const struct nf_conn *ct,
  			     enum ip_conntrack_dir dir,
  			     u32 seq)
  {
  	typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset);
  
  	return get_offset != NULL ? get_offset(ct, dir, seq) : 0;
  }
  #define NAT_OFFSET(pf, ct, dir, seq) \
  	(pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0)
  #else
  #define NAT_OFFSET(pf, ct, dir, seq)	0
  #endif
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
499
500
501
502
503
504
505
  static bool tcp_in_window(const struct nf_conn *ct,
  			  struct ip_ct_tcp *state,
  			  enum ip_conntrack_dir dir,
  			  unsigned int index,
  			  const struct sk_buff *skb,
  			  unsigned int dataoff,
  			  const struct tcphdr *tcph,
76108cea0   Jan Engelhardt   netfilter: Use un...
506
  			  u_int8_t pf)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
507
  {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
508
  	struct net *net = nf_ct_net(ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
509
510
  	struct ip_ct_tcp_state *sender = &state->seen[dir];
  	struct ip_ct_tcp_state *receiver = &state->seen[!dir];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
511
  	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
512
  	__u32 seq, ack, sack, end, win, swin;
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
513
  	s16 receiver_offset;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
514
  	bool res;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
515
516
517
518
519
520
521
522
523
524
525
  
  	/*
  	 * Get the required data from the packet.
  	 */
  	seq = ntohl(tcph->seq);
  	ack = sack = ntohl(tcph->ack_seq);
  	win = ntohs(tcph->window);
  	end = segment_seq_plus_len(seq, skb->len, dataoff, tcph);
  
  	if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
  		tcp_sack(skb, dataoff, tcph, &sack);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
526
527
528
529
  	/* Take into account NAT sequence number mangling */
  	receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1);
  	ack -= receiver_offset;
  	sack -= receiver_offset;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
530
531
532
  	pr_debug("tcp_in_window: START
  ");
  	pr_debug("tcp_in_window: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
533
  	nf_ct_dump_tuple(tuple);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
534
535
536
  	pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u
  ",
  		 seq, ack, receiver_offset, sack, receiver_offset, win, end);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
537
538
539
540
541
542
543
  	pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
  		 "receiver end=%u maxend=%u maxwin=%u scale=%i
  ",
  		 sender->td_end, sender->td_maxend, sender->td_maxwin,
  		 sender->td_scale,
  		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
  		 receiver->td_scale);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
544

874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
545
  	if (sender->td_maxwin == 0) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
546
547
548
  		/*
  		 * Initialize sender data.
  		 */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
549
  		if (tcph->syn) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
550
  			/*
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
551
552
  			 * SYN-ACK in reply to a SYN
  			 * or SYN from reply direction in simultaneous open.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
553
  			 */
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
554
  			sender->td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
555
556
557
558
  			sender->td_maxend = end;
  			sender->td_maxwin = (win == 0 ? 1 : win);
  
  			tcp_options(skb, dataoff, tcph, sender);
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
559
  			/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
560
561
562
563
564
565
  			 * RFC 1323:
  			 * Both sides must send the Window Scale option
  			 * to enable window scaling in either direction.
  			 */
  			if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
  			      && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
566
  				sender->td_scale =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
567
  				receiver->td_scale = 0;
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
568
569
570
  			if (!tcph->ack)
  				/* Simultaneous open */
  				return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
571
572
573
574
575
  		} else {
  			/*
  			 * We are in the middle of a connection,
  			 * its history is lost for us.
  			 * Let's try to use the data from the packet.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
576
  			 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
577
  			sender->td_end = end;
fac42a9a9   Pablo Neira Ayuso   netfilter: nf_ct_...
578
  			win <<= sender->td_scale;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
579
580
  			sender->td_maxwin = (win == 0 ? 1 : win);
  			sender->td_maxend = end + sender->td_maxwin;
fac42a9a9   Pablo Neira Ayuso   netfilter: nf_ct_...
581
582
583
584
585
586
587
  			/*
  			 * We haven't seen traffic in the other direction yet
  			 * but we have to tweak window tracking to pass III
  			 * and IV until that happens.
  			 */
  			if (receiver->td_maxwin == 0)
  				receiver->td_end = receiver->td_maxend = sack;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
588
589
590
591
592
593
594
595
  		}
  	} else if (((state->state == TCP_CONNTRACK_SYN_SENT
  		     && dir == IP_CT_DIR_ORIGINAL)
  		   || (state->state == TCP_CONNTRACK_SYN_RECV
  		     && dir == IP_CT_DIR_REPLY))
  		   && after(end, sender->td_end)) {
  		/*
  		 * RFC 793: "if a TCP is reinitialized ... then it need
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
596
  		 * not wait at all; it must only be sure to use sequence
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  		 * numbers larger than those recently used."
  		 */
  		sender->td_end =
  		sender->td_maxend = end;
  		sender->td_maxwin = (win == 0 ? 1 : win);
  
  		tcp_options(skb, dataoff, tcph, sender);
  	}
  
  	if (!(tcph->ack)) {
  		/*
  		 * If there is no ACK, just pretend it was set and OK.
  		 */
  		ack = sack = receiver->td_end;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
611
612
  	} else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
  		    (TCP_FLAG_ACK|TCP_FLAG_RST))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  		   && (ack == 0)) {
  		/*
  		 * Broken TCP stacks, that set ACK in RST packets as well
  		 * with zero ack value.
  		 */
  		ack = sack = receiver->td_end;
  	}
  
  	if (seq == end
  	    && (!tcph->rst
  		|| (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)))
  		/*
  		 * Packets contains no data: we assume it is valid
  		 * and check the ack value only.
  		 * However RST segments are always validated by their
  		 * SEQ number, except when seq == 0 (reset sent answering
  		 * SYN.
  		 */
  		seq = end = sender->td_end;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
632
  	pr_debug("tcp_in_window: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
633
  	nf_ct_dump_tuple(tuple);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
634
635
636
  	pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u
  ",
  		 seq, ack, receiver_offset, sack, receiver_offset, win, end);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
637
638
639
640
641
642
643
644
645
646
647
648
649
  	pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
  		 "receiver end=%u maxend=%u maxwin=%u scale=%i
  ",
  		 sender->td_end, sender->td_maxend, sender->td_maxwin,
  		 sender->td_scale,
  		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
  		 receiver->td_scale);
  
  	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i
  ",
  		 before(seq, sender->td_maxend + 1),
  		 after(end, sender->td_end - receiver->td_maxwin - 1),
  		 before(sack, receiver->td_end + 1),
84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
650
  		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
651

a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
652
653
654
  	if (before(seq, sender->td_maxend + 1) &&
  	    after(end, sender->td_end - receiver->td_maxwin - 1) &&
  	    before(sack, receiver->td_end + 1) &&
84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
655
  	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
656
  		/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
657
658
659
660
661
662
663
664
665
666
667
  		 * Take into account window scaling (RFC 1323).
  		 */
  		if (!tcph->syn)
  			win <<= sender->td_scale;
  
  		/*
  		 * Update sender data.
  		 */
  		swin = win + (sack - ack);
  		if (sender->td_maxwin < swin)
  			sender->td_maxwin = swin;
ae375044d   Patrick McHardy   netfilter: nf_con...
668
  		if (after(end, sender->td_end)) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
669
  			sender->td_end = end;
ae375044d   Patrick McHardy   netfilter: nf_con...
670
671
  			sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
  		}
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
672
673
674
675
676
677
678
  		if (tcph->ack) {
  			if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) {
  				sender->td_maxack = ack;
  				sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET;
  			} else if (after(ack, sender->td_maxack))
  				sender->td_maxack = ack;
  		}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
679
680
681
  		/*
  		 * Update receiver data.
  		 */
fac42a9a9   Pablo Neira Ayuso   netfilter: nf_ct_...
682
  		if (receiver->td_maxwin != 0 && after(end, sender->td_maxend))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
683
684
685
686
687
688
  			receiver->td_maxwin += end - sender->td_maxend;
  		if (after(sack + win, receiver->td_maxend - 1)) {
  			receiver->td_maxend = sack + win;
  			if (win == 0)
  				receiver->td_maxend++;
  		}
ae375044d   Patrick McHardy   netfilter: nf_con...
689
690
  		if (ack == receiver->td_end)
  			receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
691

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
692
  		/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
693
694
695
696
697
698
  		 * Check retransmissions.
  		 */
  		if (index == TCP_ACK_SET) {
  			if (state->last_dir == dir
  			    && state->last_seq == seq
  			    && state->last_ack == ack
c1fe3ca51   George Hansper   [NETFILTER]: TCP ...
699
700
  			    && state->last_end == end
  			    && state->last_win == win)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
701
702
703
704
705
706
  				state->retrans++;
  			else {
  				state->last_dir = dir;
  				state->last_seq = seq;
  				state->last_ack = ack;
  				state->last_end = end;
c1fe3ca51   George Hansper   [NETFILTER]: TCP ...
707
  				state->last_win = win;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
708
709
710
  				state->retrans = 0;
  			}
  		}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
711
  		res = true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
712
  	} else {
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
713
  		res = false;
a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
714
715
  		if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
  		    nf_ct_tcp_be_liberal)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
716
  			res = true;
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
717
  		if (!res && LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
718
719
720
721
722
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  			"nf_ct_tcp: %s ",
  			before(seq, sender->td_maxend + 1) ?
  			after(end, sender->td_end - receiver->td_maxwin - 1) ?
  			before(sack, receiver->td_end + 1) ?
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
723
  			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
724
725
726
727
  			: "ACK is under the lower bound (possible overly delayed ACK)"
  			: "ACK is over the upper bound (ACKed data not seen yet)"
  			: "SEQ is under the lower bound (already ACKed data retransmitted)"
  			: "SEQ is over the upper bound (over the window of the receiver)");
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
728
  	}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
729
  	pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
730
731
732
733
  		 "receiver end=%u maxend=%u maxwin=%u
  ",
  		 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
  		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
734
735
736
  
  	return res;
  }
5c8ce7c92   Willy Tarreau   [NETFILTER]: TCP ...
737
  /* table of valid flag combinations - PUSH, ECE and CWR are always valid */
a3433f35a   Changli Gao   tcp: unify tcp fl...
738
739
  static const u8 tcp_valid_flags[(TCPHDR_FIN|TCPHDR_SYN|TCPHDR_RST|TCPHDR_ACK|
  				 TCPHDR_URG) + 1] =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
740
  {
a3433f35a   Changli Gao   tcp: unify tcp fl...
741
742
743
744
745
746
747
748
749
  	[TCPHDR_SYN]				= 1,
  	[TCPHDR_SYN|TCPHDR_URG]			= 1,
  	[TCPHDR_SYN|TCPHDR_ACK]			= 1,
  	[TCPHDR_RST]				= 1,
  	[TCPHDR_RST|TCPHDR_ACK]			= 1,
  	[TCPHDR_FIN|TCPHDR_ACK]			= 1,
  	[TCPHDR_FIN|TCPHDR_ACK|TCPHDR_URG]	= 1,
  	[TCPHDR_ACK]				= 1,
  	[TCPHDR_ACK|TCPHDR_URG]			= 1,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
750
751
752
  };
  
  /* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c.  */
8fea97ec1   Patrick McHardy   netfilter: nf_con...
753
  static int tcp_error(struct net *net, struct nf_conn *tmpl,
74c51a149   Alexey Dobriyan   netfilter: netns ...
754
  		     struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
755
756
  		     unsigned int dataoff,
  		     enum ip_conntrack_info *ctinfo,
76108cea0   Jan Engelhardt   netfilter: Use un...
757
  		     u_int8_t pf,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
758
  		     unsigned int hooknum)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
759
  {
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
760
761
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
762
763
764
765
766
767
  	unsigned int tcplen = skb->len - dataoff;
  	u_int8_t tcpflags;
  
  	/* Smaller that minimal TCP header? */
  	th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
  	if (th == NULL) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
768
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
769
770
771
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  				"nf_ct_tcp: short packet ");
  		return -NF_ACCEPT;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
772
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
773
774
  	/* Not whole TCP header or malformed packet */
  	if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
775
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
776
777
778
779
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  				"nf_ct_tcp: truncated/malformed packet ");
  		return -NF_ACCEPT;
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
780

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
781
782
  	/* Checksum invalid? Ignore.
  	 * We skip checking packets on the outgoing path
84fa7933a   Patrick McHardy   [NET]: Replace CH...
783
  	 * because the checksum is assumed to be correct.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
784
785
  	 */
  	/* FIXME: Source route IP option packets --RR */
c04d05529   Alexey Dobriyan   netfilter: netns ...
786
  	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
787
  	    nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
788
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
789
790
791
792
793
794
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  				  "nf_ct_tcp: bad TCP checksum ");
  		return -NF_ACCEPT;
  	}
  
  	/* Check TCP flags. */
a3433f35a   Changli Gao   tcp: unify tcp fl...
795
  	tcpflags = (tcp_flag_byte(th) & ~(TCPHDR_ECE|TCPHDR_CWR|TCPHDR_PSH));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
796
  	if (!tcp_valid_flags[tcpflags]) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
797
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
798
799
800
801
802
803
804
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  				  "nf_ct_tcp: invalid TCP flag combination ");
  		return -NF_ACCEPT;
  	}
  
  	return NF_ACCEPT;
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
805
  /* Returns verdict for packet, or -1 for invalid. */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
806
  static int tcp_packet(struct nf_conn *ct,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
807
808
809
  		      const struct sk_buff *skb,
  		      unsigned int dataoff,
  		      enum ip_conntrack_info ctinfo,
76108cea0   Jan Engelhardt   netfilter: Use un...
810
  		      u_int8_t pf,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
811
812
  		      unsigned int hooknum)
  {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
813
  	struct net *net = nf_ct_net(ct);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
814
  	struct nf_conntrack_tuple *tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
815
816
  	enum tcp_conntrack new_state, old_state;
  	enum ip_conntrack_dir dir;
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
817
818
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
819
820
821
822
823
  	unsigned long timeout;
  	unsigned int index;
  
  	th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
  	BUG_ON(th == NULL);
440f0d588   Patrick McHardy   netfilter: nf_con...
824
  	spin_lock_bh(&ct->lock);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
825
  	old_state = ct->proto.tcp.state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
826
827
828
  	dir = CTINFO2DIR(ctinfo);
  	index = get_conntrack_index(th);
  	new_state = tcp_conntracks[dir][index][old_state];
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
829
  	tuple = &ct->tuplehash[dir].tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
830
831
  
  	switch (new_state) {
17311393f   Jozsef Kadlecsik   [NETFILTER]: nf_c...
832
833
834
  	case TCP_CONNTRACK_SYN_SENT:
  		if (old_state < TCP_CONNTRACK_TIME_WAIT)
  			break;
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
  		/* RFC 1122: "When a connection is closed actively,
  		 * it MUST linger in TIME-WAIT state for a time 2xMSL
  		 * (Maximum Segment Lifetime). However, it MAY accept
  		 * a new SYN from the remote TCP to reopen the connection
  		 * directly from TIME-WAIT state, if..."
  		 * We ignore the conditions because we are in the
  		 * TIME-WAIT state anyway.
  		 *
  		 * Handle aborted connections: we and the server
  		 * think there is an existing connection but the client
  		 * aborts it and starts a new one.
  		 */
  		if (((ct->proto.tcp.seen[dir].flags
  		      | ct->proto.tcp.seen[!dir].flags)
  		     & IP_CT_TCP_FLAG_CLOSE_INIT)
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
850
851
  		    || (ct->proto.tcp.last_dir == dir
  		        && ct->proto.tcp.last_index == TCP_RST_SET)) {
bc34b8415   Jozsef Kadlecsik   [NETFILTER]: nf_c...
852
853
  			/* Attempt to reopen a closed/aborted connection.
  			 * Delete this connection and look up again. */
440f0d588   Patrick McHardy   netfilter: nf_con...
854
  			spin_unlock_bh(&ct->lock);
2aec609fb   David S. Miller   Merge branch 'mas...
855

6b69fe0c7   Patrick McHardy   netfilter: nf_con...
856
857
858
859
  			/* Only repeat if we can actually remove the timer.
  			 * Destruction may already be in progress in process
  			 * context and we must give it a chance to terminate.
  			 */
2aec609fb   David S. Miller   Merge branch 'mas...
860
  			if (nf_ct_kill(ct))
6b69fe0c7   Patrick McHardy   netfilter: nf_con...
861
  				return -NF_REPEAT;
ec8d54096   Christoph Paasch   netfilter: conntr...
862
  			return NF_DROP;
17311393f   Jozsef Kadlecsik   [NETFILTER]: nf_c...
863
864
  		}
  		/* Fall through */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
865
  	case TCP_CONNTRACK_IGNORE:
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
866
867
  		/* Ignored packets:
  		 *
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
868
869
870
871
  		 * Our connection entry may be out of sync, so ignore
  		 * packets which may signal the real connection between
  		 * the client and the server.
  		 *
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
872
873
  		 * a) SYN in ORIGINAL
  		 * b) SYN/ACK in REPLY
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
874
  		 * c) ACK in reply direction after initial SYN in original.
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
875
876
877
  		 *
  		 * If the ignored packet is invalid, the receiver will send
  		 * a RST we'll catch below.
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
878
  		 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
879
  		if (index == TCP_SYNACK_SET
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
880
881
882
  		    && ct->proto.tcp.last_index == TCP_SYN_SET
  		    && ct->proto.tcp.last_dir != dir
  		    && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
883
  			/* b) This SYN/ACK acknowledges a SYN that we earlier
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
884
885
  			 * ignored as invalid. This means that the client and
  			 * the server are both in sync, while the firewall is
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
886
887
  			 * not. We get in sync from the previously annotated
  			 * values.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
888
  			 */
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
  			old_state = TCP_CONNTRACK_SYN_SENT;
  			new_state = TCP_CONNTRACK_SYN_RECV;
  			ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_end =
  				ct->proto.tcp.last_end;
  			ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxend =
  				ct->proto.tcp.last_end;
  			ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_maxwin =
  				ct->proto.tcp.last_win == 0 ?
  					1 : ct->proto.tcp.last_win;
  			ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
  				ct->proto.tcp.last_wscale;
  			ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
  				ct->proto.tcp.last_flags;
  			memset(&ct->proto.tcp.seen[dir], 0,
  			       sizeof(struct ip_ct_tcp_state));
  			break;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
905
  		}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
906
907
908
909
  		ct->proto.tcp.last_index = index;
  		ct->proto.tcp.last_dir = dir;
  		ct->proto.tcp.last_seq = ntohl(th->seq);
  		ct->proto.tcp.last_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
910
  		    segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
  		ct->proto.tcp.last_win = ntohs(th->window);
  
  		/* a) This is a SYN in ORIGINAL. The client and the server
  		 * may be in sync but we are not. In that case, we annotate
  		 * the TCP options and let the packet go through. If it is a
  		 * valid SYN packet, the server will reply with a SYN/ACK, and
  		 * then we'll get in sync. Otherwise, the server ignores it. */
  		if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
  			struct ip_ct_tcp_state seen = {};
  
  			ct->proto.tcp.last_flags =
  			ct->proto.tcp.last_wscale = 0;
  			tcp_options(skb, dataoff, th, &seen);
  			if (seen.flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
  				ct->proto.tcp.last_flags |=
  					IP_CT_TCP_FLAG_WINDOW_SCALE;
  				ct->proto.tcp.last_wscale = seen.td_scale;
  			}
  			if (seen.flags & IP_CT_TCP_FLAG_SACK_PERM) {
  				ct->proto.tcp.last_flags |=
  					IP_CT_TCP_FLAG_SACK_PERM;
  			}
  		}
440f0d588   Patrick McHardy   netfilter: nf_con...
934
  		spin_unlock_bh(&ct->lock);
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
935
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
936
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
937
  				  "nf_ct_tcp: invalid packet ignored ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
938
939
940
  		return NF_ACCEPT;
  	case TCP_CONNTRACK_MAX:
  		/* Invalid packet */
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
941
942
943
  		pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u
  ",
  			 dir, get_conntrack_index(th), old_state);
440f0d588   Patrick McHardy   netfilter: nf_con...
944
  		spin_unlock_bh(&ct->lock);
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
945
  		if (LOG_INVALID(net, IPPROTO_TCP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
946
947
948
  			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  				  "nf_ct_tcp: invalid state ");
  		return -NF_ACCEPT;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
949
950
  	case TCP_CONNTRACK_CLOSE:
  		if (index == TCP_RST_SET
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
951
952
953
  		    && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
  		    && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
  			/* Invalid RST  */
334a47f63   Patrick McHardy   netfilter: nf_ct_...
954
  			spin_unlock_bh(&ct->lock);
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
955
956
957
958
959
960
  			if (LOG_INVALID(net, IPPROTO_TCP))
  				nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
  					  "nf_ct_tcp: invalid RST ");
  			return -NF_ACCEPT;
  		}
  		if (index == TCP_RST_SET
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
961
962
963
964
965
  		    && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
  			 && ct->proto.tcp.last_index == TCP_SYN_SET)
  			|| (!test_bit(IPS_ASSURED_BIT, &ct->status)
  			    && ct->proto.tcp.last_index == TCP_ACK_SET))
  		    && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
93b1fae49   Adrian Bunk   spelling: s/troug...
966
  			/* RST sent to invalid SYN or ACK we had let through
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
967
968
969
970
971
972
  			 * at a) and c) above:
  			 *
  			 * a) SYN was in window then
  			 * c) we hold a half-open connection.
  			 *
  			 * Delete our connection entry.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
973
  			 * We skip window checking, because packet might ACK
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
974
  			 * segments we ignored. */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
975
976
  			goto in_window;
  		}
93b1fae49   Adrian Bunk   spelling: s/troug...
977
  		/* Just fall through */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
978
979
980
981
  	default:
  		/* Keep compilers happy. */
  		break;
  	}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
982
  	if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
983
  			   skb, dataoff, th, pf)) {
440f0d588   Patrick McHardy   netfilter: nf_con...
984
  		spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
985
986
987
988
  		return -NF_ACCEPT;
  	}
       in_window:
  	/* From now on we have got in-window packets */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
989
990
  	ct->proto.tcp.last_index = index;
  	ct->proto.tcp.last_dir = dir;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
991

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
992
  	pr_debug("tcp_conntracks: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
993
  	nf_ct_dump_tuple(tuple);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
994
995
996
997
998
  	pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i
  ",
  		 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
  		 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
  		 old_state, new_state);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
999

c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1000
  	ct->proto.tcp.state = new_state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1001
  	if (old_state != new_state
d0c1fd7a8   Jozsef Kadlecsik   [NETFILTER] nf_co...
1002
  	    && new_state == TCP_CONNTRACK_FIN_WAIT)
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1003
  		ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
ae375044d   Patrick McHardy   netfilter: nf_con...
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
  
  	if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
  	    tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans)
  		timeout = nf_ct_tcp_timeout_max_retrans;
  	else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
  		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
  		 tcp_timeouts[new_state] > nf_ct_tcp_timeout_unacknowledged)
  		timeout = nf_ct_tcp_timeout_unacknowledged;
  	else
  		timeout = tcp_timeouts[new_state];
440f0d588   Patrick McHardy   netfilter: nf_con...
1014
  	spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1015

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1016
  	if (new_state != old_state)
a71996fcc   Alexey Dobriyan   netfilter: netns ...
1017
  		nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1018

c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1019
  	if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1020
1021
1022
1023
1024
  		/* If only reply is a RST, we can consider ourselves not to
  		   have an established connection: this is a fairly common
  		   problem case, so we can delete the conntrack
  		   immediately.  --RR */
  		if (th->rst) {
718d4ad98   Fabian Hugelshofer   netfilter: nf_con...
1025
  			nf_ct_kill_acct(ct, ctinfo, skb);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1026
1027
  			return NF_ACCEPT;
  		}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1028
  	} else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1029
1030
1031
  		   && (old_state == TCP_CONNTRACK_SYN_RECV
  		       || old_state == TCP_CONNTRACK_ESTABLISHED)
  		   && new_state == TCP_CONNTRACK_ESTABLISHED) {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1032
1033
  		/* Set ASSURED if we see see valid ack in ESTABLISHED
  		   after SYN_RECV or a valid answer for a picked up
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1034
  		   connection. */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1035
  		set_bit(IPS_ASSURED_BIT, &ct->status);
858b31330   Patrick McHardy   netfilter: nf_con...
1036
  		nf_conntrack_event_cache(IPCT_ASSURED, ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1037
  	}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1038
  	nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1039
1040
1041
  
  	return NF_ACCEPT;
  }
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1042

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1043
  /* Called when a new connection for this protocol found. */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1044
1045
  static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
  		    unsigned int dataoff)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1046
1047
  {
  	enum tcp_conntrack new_state;
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
1048
1049
1050
1051
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
  	const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
  	const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1052
1053
1054
1055
1056
  
  	th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
  	BUG_ON(th == NULL);
  
  	/* Don't need lock here: this conntrack not in circulation yet */
e5fc9e7a6   Changli Gao   netfilter: nf_con...
1057
  	new_state = tcp_conntracks[0][get_conntrack_index(th)][TCP_CONNTRACK_NONE];
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1058
1059
1060
  
  	/* Invalid: delete conntrack */
  	if (new_state >= TCP_CONNTRACK_MAX) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1061
1062
  		pr_debug("nf_ct_tcp: invalid new deleting.
  ");
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1063
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1064
1065
1066
  	}
  
  	if (new_state == TCP_CONNTRACK_SYN_SENT) {
e5fc9e7a6   Changli Gao   netfilter: nf_con...
1067
  		memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1068
  		/* SYN packet */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1069
  		ct->proto.tcp.seen[0].td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1070
1071
  			segment_seq_plus_len(ntohl(th->seq), skb->len,
  					     dataoff, th);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1072
1073
1074
1075
1076
1077
1078
  		ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
  		if (ct->proto.tcp.seen[0].td_maxwin == 0)
  			ct->proto.tcp.seen[0].td_maxwin = 1;
  		ct->proto.tcp.seen[0].td_maxend =
  			ct->proto.tcp.seen[0].td_end;
  
  		tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1079
1080
  	} else if (nf_ct_tcp_loose == 0) {
  		/* Don't try to pick up connections. */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1081
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1082
  	} else {
e5fc9e7a6   Changli Gao   netfilter: nf_con...
1083
  		memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1084
1085
1086
1087
1088
  		/*
  		 * We are in the middle of a connection,
  		 * its history is lost for us.
  		 * Let's try to use the data from the packet.
  		 */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1089
  		ct->proto.tcp.seen[0].td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1090
1091
  			segment_seq_plus_len(ntohl(th->seq), skb->len,
  					     dataoff, th);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1092
1093
1094
1095
1096
1097
  		ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
  		if (ct->proto.tcp.seen[0].td_maxwin == 0)
  			ct->proto.tcp.seen[0].td_maxwin = 1;
  		ct->proto.tcp.seen[0].td_maxend =
  			ct->proto.tcp.seen[0].td_end +
  			ct->proto.tcp.seen[0].td_maxwin;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1098

a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
1099
1100
  		/* We assume SACK and liberal window checking to handle
  		 * window scaling */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1101
1102
1103
  		ct->proto.tcp.seen[0].flags =
  		ct->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
  					      IP_CT_TCP_FLAG_BE_LIBERAL;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1104
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1105

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1106
  	/* tcp_packet will set them */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1107
  	ct->proto.tcp.last_index = TCP_NONE_SET;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1108

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1109
1110
1111
1112
1113
1114
1115
  	pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
  		 "receiver end=%u maxend=%u maxwin=%u scale=%i
  ",
  		 sender->td_end, sender->td_maxend, sender->td_maxwin,
  		 sender->td_scale,
  		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
  		 receiver->td_scale);
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1116
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1117
  }
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1118

c0cd11566   Igor Maravić   net:netfilter: us...
1119
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1120
1121
1122
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_conntrack.h>
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1123
  static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
440f0d588   Patrick McHardy   netfilter: nf_con...
1124
  			 struct nf_conn *ct)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1125
  {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1126
  	struct nlattr *nest_parms;
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1127
  	struct nf_ct_tcp_flags tmp = {};
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1128

440f0d588   Patrick McHardy   netfilter: nf_con...
1129
  	spin_lock_bh(&ct->lock);
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1130
1131
1132
  	nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
  	if (!nest_parms)
  		goto nla_put_failure;
77236b6e3   Patrick McHardy   [NETFILTER]: ctne...
1133
  	NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1134

77236b6e3   Patrick McHardy   [NETFILTER]: ctne...
1135
1136
  	NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
  		   ct->proto.tcp.seen[0].td_scale);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1137

77236b6e3   Patrick McHardy   [NETFILTER]: ctne...
1138
1139
  	NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
  		   ct->proto.tcp.seen[1].td_scale);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1140
1141
  
  	tmp.flags = ct->proto.tcp.seen[0].flags;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1142
  	NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1143
1144
1145
  		sizeof(struct nf_ct_tcp_flags), &tmp);
  
  	tmp.flags = ct->proto.tcp.seen[1].flags;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1146
  	NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1147
  		sizeof(struct nf_ct_tcp_flags), &tmp);
440f0d588   Patrick McHardy   netfilter: nf_con...
1148
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1149

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1150
  	nla_nest_end(skb, nest_parms);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1151
1152
  
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1153
  nla_put_failure:
440f0d588   Patrick McHardy   netfilter: nf_con...
1154
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1155
1156
  	return -1;
  }
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1157
1158
1159
1160
1161
1162
  static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
  	[CTA_PROTOINFO_TCP_STATE]	    = { .type = NLA_U8 },
  	[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 },
  	[CTA_PROTOINFO_TCP_WSCALE_REPLY]    = { .type = NLA_U8 },
  	[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]  = { .len = sizeof(struct nf_ct_tcp_flags) },
  	[CTA_PROTOINFO_TCP_FLAGS_REPLY]	    = { .len =  sizeof(struct nf_ct_tcp_flags) },
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1163
  };
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1164
  static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1165
  {
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
1166
  	struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1167
  	struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1168
  	int err;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1169
1170
1171
  
  	/* updates could not contain anything about the private
  	 * protocol info, in that case skip the parsing */
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
1172
  	if (!pattr)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1173
  		return 0;
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
1174
  	err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1175
1176
  	if (err < 0)
  		return err;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1177

5f7da4d26   Patrick McHardy   [NETFILTER]: nf_c...
1178
1179
  	if (tb[CTA_PROTOINFO_TCP_STATE] &&
  	    nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1180
  		return -EINVAL;
440f0d588   Patrick McHardy   netfilter: nf_con...
1181
  	spin_lock_bh(&ct->lock);
5f7da4d26   Patrick McHardy   [NETFILTER]: nf_c...
1182
1183
  	if (tb[CTA_PROTOINFO_TCP_STATE])
  		ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1184

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1185
  	if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1186
  		struct nf_ct_tcp_flags *attr =
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1187
  			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1188
1189
1190
  		ct->proto.tcp.seen[0].flags &= ~attr->mask;
  		ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1191
  	if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1192
  		struct nf_ct_tcp_flags *attr =
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1193
  			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1194
1195
1196
  		ct->proto.tcp.seen[1].flags &= ~attr->mask;
  		ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1197
1198
  	if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&
  	    tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1199
1200
  	    ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
  	    ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
77236b6e3   Patrick McHardy   [NETFILTER]: ctne...
1201
1202
1203
1204
  		ct->proto.tcp.seen[0].td_scale =
  			nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
  		ct->proto.tcp.seen[1].td_scale =
  			nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1205
  	}
440f0d588   Patrick McHardy   netfilter: nf_con...
1206
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1207
1208
1209
  
  	return 0;
  }
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
  
  static int tcp_nlattr_size(void)
  {
  	return nla_total_size(0)	   /* CTA_PROTOINFO_TCP */
  		+ nla_policy_len(tcp_nla_policy, CTA_PROTOINFO_TCP_MAX + 1);
  }
  
  static int tcp_nlattr_tuple_size(void)
  {
  	return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
  }
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1221
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1222
1223
1224
1225
1226
1227
  
  #ifdef CONFIG_SYSCTL
  static unsigned int tcp_sysctl_table_users;
  static struct ctl_table_header *tcp_sysctl_header;
  static struct ctl_table tcp_sysctl_table[] = {
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1228
  		.procname	= "nf_conntrack_tcp_timeout_syn_sent",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1229
  		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1230
1231
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1232
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1233
1234
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1235
  		.procname	= "nf_conntrack_tcp_timeout_syn_recv",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1236
  		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1237
1238
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1239
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1240
1241
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1242
  		.procname	= "nf_conntrack_tcp_timeout_established",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1243
  		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1244
1245
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1246
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1247
1248
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1249
  		.procname	= "nf_conntrack_tcp_timeout_fin_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1250
  		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1251
1252
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1253
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1254
1255
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1256
  		.procname	= "nf_conntrack_tcp_timeout_close_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1257
  		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1258
1259
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1260
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1261
1262
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1263
  		.procname	= "nf_conntrack_tcp_timeout_last_ack",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1264
  		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1265
1266
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1267
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1268
1269
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1270
  		.procname	= "nf_conntrack_tcp_timeout_time_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1271
  		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1272
1273
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1274
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1275
1276
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1277
  		.procname	= "nf_conntrack_tcp_timeout_close",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1278
  		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1279
1280
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1281
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1282
1283
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1284
1285
1286
1287
  		.procname	= "nf_conntrack_tcp_timeout_max_retrans",
  		.data		= &nf_ct_tcp_timeout_max_retrans,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1288
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1289
1290
  	},
  	{
ae375044d   Patrick McHardy   netfilter: nf_con...
1291
1292
1293
1294
  		.procname	= "nf_conntrack_tcp_timeout_unacknowledged",
  		.data		= &nf_ct_tcp_timeout_unacknowledged,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1295
  		.proc_handler	= proc_dointvec_jiffies,
ae375044d   Patrick McHardy   netfilter: nf_con...
1296
1297
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1298
1299
1300
1301
  		.procname	= "nf_conntrack_tcp_loose",
  		.data		= &nf_ct_tcp_loose,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1302
  		.proc_handler	= proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1303
1304
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1305
1306
1307
1308
  		.procname       = "nf_conntrack_tcp_be_liberal",
  		.data           = &nf_ct_tcp_be_liberal,
  		.maxlen         = sizeof(unsigned int),
  		.mode           = 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1309
  		.proc_handler   = proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1310
1311
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1312
1313
1314
1315
  		.procname	= "nf_conntrack_tcp_max_retrans",
  		.data		= &nf_ct_tcp_max_retrans,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1316
  		.proc_handler	= proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1317
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
1318
  	{ }
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1319
  };
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1320
1321
1322
1323
  
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  static struct ctl_table tcp_compat_sysctl_table[] = {
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1324
  		.procname	= "ip_conntrack_tcp_timeout_syn_sent",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1325
  		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1326
1327
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1328
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1329
1330
  	},
  	{
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
1331
1332
1333
1334
1335
1336
1337
  		.procname	= "ip_conntrack_tcp_timeout_syn_sent2",
  		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_SENT2],
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
  		.proc_handler	= proc_dointvec_jiffies,
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1338
  		.procname	= "ip_conntrack_tcp_timeout_syn_recv",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1339
  		.data		= &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1340
1341
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1342
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1343
1344
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1345
  		.procname	= "ip_conntrack_tcp_timeout_established",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1346
  		.data		= &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1347
1348
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1349
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1350
1351
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1352
  		.procname	= "ip_conntrack_tcp_timeout_fin_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1353
  		.data		= &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1354
1355
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1356
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1357
1358
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1359
  		.procname	= "ip_conntrack_tcp_timeout_close_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1360
  		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1361
1362
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1363
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1364
1365
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1366
  		.procname	= "ip_conntrack_tcp_timeout_last_ack",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1367
  		.data		= &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1368
1369
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1370
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1371
1372
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1373
  		.procname	= "ip_conntrack_tcp_timeout_time_wait",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1374
  		.data		= &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1375
1376
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1377
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1378
1379
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1380
  		.procname	= "ip_conntrack_tcp_timeout_close",
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
1381
  		.data		= &tcp_timeouts[TCP_CONNTRACK_CLOSE],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1382
1383
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1384
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1385
1386
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1387
1388
1389
1390
  		.procname	= "ip_conntrack_tcp_timeout_max_retrans",
  		.data		= &nf_ct_tcp_timeout_max_retrans,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1391
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1392
1393
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1394
1395
1396
1397
  		.procname	= "ip_conntrack_tcp_loose",
  		.data		= &nf_ct_tcp_loose,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1398
  		.proc_handler	= proc_dointvec,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1399
1400
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1401
1402
1403
1404
  		.procname	= "ip_conntrack_tcp_be_liberal",
  		.data		= &nf_ct_tcp_be_liberal,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1405
  		.proc_handler	= proc_dointvec,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1406
1407
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1408
1409
1410
1411
  		.procname	= "ip_conntrack_tcp_max_retrans",
  		.data		= &nf_ct_tcp_max_retrans,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1412
  		.proc_handler	= proc_dointvec,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1413
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
1414
  	{ }
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1415
1416
  };
  #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1417
  #endif /* CONFIG_SYSCTL */
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
1418
  struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1419
1420
  {
  	.l3proto		= PF_INET,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1421
  	.l4proto 		= IPPROTO_TCP,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1422
1423
1424
1425
1426
1427
1428
  	.name 			= "tcp",
  	.pkt_to_tuple 		= tcp_pkt_to_tuple,
  	.invert_tuple 		= tcp_invert_tuple,
  	.print_tuple 		= tcp_print_tuple,
  	.print_conntrack 	= tcp_print_conntrack,
  	.packet 		= tcp_packet,
  	.new 			= tcp_new,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
1429
  	.error			= tcp_error,
c0cd11566   Igor Maravić   net:netfilter: us...
1430
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1431
  	.to_nlattr		= tcp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1432
  	.nlattr_size		= tcp_nlattr_size,
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1433
1434
1435
  	.from_nlattr		= nlattr_to_tcp,
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1436
  	.nlattr_tuple_size	= tcp_nlattr_tuple_size,
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1437
  	.nla_policy		= nf_ct_port_nla_policy,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1438
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1439
1440
1441
1442
  #ifdef CONFIG_SYSCTL
  	.ctl_table_users	= &tcp_sysctl_table_users,
  	.ctl_table_header	= &tcp_sysctl_header,
  	.ctl_table		= tcp_sysctl_table,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
1443
1444
1445
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  	.ctl_compat_table	= tcp_compat_sysctl_table,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1446
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1447
  };
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1448
  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1449

61075af51   Patrick McHardy   [NETFILTER]: nf_c...
1450
  struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1451
1452
  {
  	.l3proto		= PF_INET6,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1453
  	.l4proto 		= IPPROTO_TCP,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1454
1455
1456
1457
1458
1459
1460
  	.name 			= "tcp",
  	.pkt_to_tuple 		= tcp_pkt_to_tuple,
  	.invert_tuple 		= tcp_invert_tuple,
  	.print_tuple 		= tcp_print_tuple,
  	.print_conntrack 	= tcp_print_conntrack,
  	.packet 		= tcp_packet,
  	.new 			= tcp_new,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
1461
  	.error			= tcp_error,
c0cd11566   Igor Maravić   net:netfilter: us...
1462
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1463
  	.to_nlattr		= tcp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1464
  	.nlattr_size		= tcp_nlattr_size,
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1465
1466
1467
  	.from_nlattr		= nlattr_to_tcp,
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1468
  	.nlattr_tuple_size	= tcp_nlattr_tuple_size,
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1469
  	.nla_policy		= nf_ct_port_nla_policy,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1470
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1471
1472
1473
1474
1475
  #ifdef CONFIG_SYSCTL
  	.ctl_table_users	= &tcp_sysctl_table_users,
  	.ctl_table_header	= &tcp_sysctl_header,
  	.ctl_table		= tcp_sysctl_table,
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1476
  };
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1477
  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);