Blame view

net/netfilter/nf_conntrack_proto_tcp.c 49.5 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
  /* (C) 1999-2001 Paul `Rusty' Russell
   * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
f229f6ce4   Patrick McHardy   netfilter: add my...
3
4
   * (C) 2002-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
   * (C) 2006-2012 Patrick McHardy <kaber@trash.net>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
5
6
7
8
   *
   * 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 ...
9
   */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
10
  #include <linux/types.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
11
  #include <linux/timer.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
12
13
14
15
16
17
18
  #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...
19
  #include <asm/unaligned.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
20
21
22
23
24
25
26
  
  #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...
27
  #include <net/netfilter/nf_conntrack_l4proto.h>
f61801218   Martin Josefsson   [NETFILTER]: nf_c...
28
  #include <net/netfilter/nf_conntrack_ecache.h>
41d73ec05   Patrick McHardy   netfilter: nf_con...
29
  #include <net/netfilter/nf_conntrack_seqadj.h>
48b1de4c1   Patrick McHardy   netfilter: add SY...
30
  #include <net/netfilter/nf_conntrack_synproxy.h>
f01ffbd6e   Patrick McHardy   [NETFILTER]: nf_l...
31
  #include <net/netfilter/nf_log.h>
9d2493f88   Christoph Paasch   netfilter: remove...
32
33
  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
34

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

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

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
44
45
  /* 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 ...
46
     will be started. */
3aef0fd91   Patrick McHardy   [NETFILTER]: nf_c...
47
  static int nf_ct_tcp_max_retrans __read_mostly = 3;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
48
49
50
  
    /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
       closely.  They're more complex. --RR */
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
51
  static const char *const tcp_conntrack_names[] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
52
53
54
55
56
57
58
59
60
  	"NONE",
  	"SYN_SENT",
  	"SYN_RECV",
  	"ESTABLISHED",
  	"FIN_WAIT",
  	"CLOSE_WAIT",
  	"LAST_ACK",
  	"TIME_WAIT",
  	"CLOSE",
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
61
  	"SYN_SENT2",
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
62
  };
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
63

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
64
65
66
67
  #define SECS * HZ
  #define MINS * 60 SECS
  #define HOURS * 60 MINS
  #define DAYS * 24 HOURS
33ee44643   Pablo Neira Ayuso   netfilter: nf_ct_...
68
  static unsigned int tcp_timeouts[TCP_CONNTRACK_TIMEOUT_MAX] __read_mostly = {
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
69
70
71
72
73
74
75
76
  	[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_...
77
  	[TCP_CONNTRACK_SYN_SENT2]	= 2 MINS,
33ee44643   Pablo Neira Ayuso   netfilter: nf_ct_...
78
79
80
81
82
  /* RFC1122 says the R2 limit should be at least 100 seconds.
     Linux uses 15 packets as limit, which corresponds
     to ~13-30min depending on RTO. */
  	[TCP_CONNTRACK_RETRANS]		= 5 MINS,
  	[TCP_CONNTRACK_UNACK]		= 5 MINS,
2d6462869   Patrick McHardy   [NETFILTER]: nf_c...
83
  };
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
84

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
85
86
87
88
89
90
91
92
93
  #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_...
94
  #define sS2 TCP_CONNTRACK_SYN_SENT2
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
95
96
97
98
99
100
101
102
103
104
105
106
  #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 ...
107

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
108
109
110
111
112
  /*
   * 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 ...
113
   * It is assumed that the destinations can't receive segments
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
114
115
116
117
118
119
120
121
122
   * 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 ...
123
   * SYN_SENT:	SYN-only packet seen
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
124
   * SYN_SENT2:	SYN-only packet seen from reply dir, simultaneous open
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
125
126
127
   * SYN_RECV:	SYN-ACK packet seen
   * ESTABLISHED:	ACK packet seen
   * FIN_WAIT:	FIN packet seen
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
128
   * CLOSE_WAIT:	ACK seen (after FIN)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
129
130
   * LAST_ACK:	FIN seen (after FIN)
   * TIME_WAIT:	last ACK seen
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
131
   * CLOSE:	closed connection (RST)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
132
   *
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
133
   * Packets marked as IGNORED (sIG):
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
134
135
   *	if they may be either invalid or valid
   *	and the receiver may send back a connection
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
136
137
138
   *	closing RST or a SYN/ACK.
   *
   * Packets marked as INVALID (sIV):
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
139
   *	if we regard them as truly invalid packets
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
140
   */
a5e73c29d   Patrick McHardy   [NETFILTER]: nf_c...
141
  static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
142
143
  	{
  /* ORIGINAL */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
144
145
  /* 	     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 ...
146
147
148
  /*
   *	sNO -> sSS	Initialize a new connection
   *	sSS -> sSS	Retransmitted SYN
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
149
150
   *	sS2 -> sS2	Late retransmitted SYN
   *	sSR -> sIG
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
151
   *	sES -> sIG	Error: SYNs in window outside the SYN_SENT state
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
152
   *			are errors. Receiver will reply with RST
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
153
154
155
156
157
158
159
160
   *			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_...
161
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
64f509ce7   Jozsef Kadlecsik   netfilter: Mark S...
162
  /*synack*/ { sIV, sIV, sSR, sIV, sIV, sIV, sIV, sIV, sIV, sSR },
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
163
  /*
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
164
165
166
   *	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
64f509ce7   Jozsef Kadlecsik   netfilter: Mark S...
167
168
169
170
171
172
173
   *	sSR -> sSR	Late retransmitted SYN/ACK in simultaneous open
   *	sES -> sIV	Invalid SYN/ACK packets sent by the client
   *	sFW -> sIV
   *	sCW -> sIV
   *	sLA -> sIV
   *	sTW -> sIV
   *	sCL -> sIV
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
   *	sSR -> sES	Established state is reached.
   *	sES -> sES	:-)
   *	sFW -> sCW	Normal close request answered by ACK.
   *	sCW -> sCW
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
202
   *	sLA -> sTW	Last ACK detected (RFC5961 challenged)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
203
204
205
   *	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
  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/
e37ad9fd6   Marcelo Leitner   netfilter: nf_con...
213
  /*syn*/	   { sIV, sS2, sIV, sIV, sIV, sIV, sIV, sSS, 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
   *	sFW -> sIV
   *	sCW -> sIV
   *	sLA -> sIV
e37ad9fd6   Marcelo Leitner   netfilter: nf_con...
223
   *	sTW -> sSS	Reopened connection, but server may have switched role
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
224
225
   *	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
   *	sSR -> sSR	Might answer late resent SYN.
   *	sES -> sES	:-)
   *	sFW -> sCW	Normal close request answered by ACK.
   *	sCW -> sCW
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
261
   *	sLA -> sTW	Last ACK detected (RFC5961 challenged)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
262
263
264
   *	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
  };
d2ba1fde4   Gao feng   netfilter: nf_ct_...
270
271
272
273
  static inline struct nf_tcp_net *tcp_pernet(struct net *net)
  {
  	return &net->ct.nf_ct_proto.tcp;
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
274
  static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
a31f1adc0   Eric W. Biederman   netfilter: nf_con...
275
  			     struct net *net, struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
276
  {
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
277
278
  	const struct tcphdr *hp;
  	struct tcphdr _hdr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
279

e5e693ab4   Gao Feng   netfilter: conntr...
280
281
  	/* Actually only need first 4 bytes to get ports. */
  	hp = skb_header_pointer(skb, dataoff, 4, &_hdr);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
282
  	if (hp == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
283
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
284
285
286
  
  	tuple->src.u.tcp.port = hp->source;
  	tuple->dst.u.tcp.port = hp->dest;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
287
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
288
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
289
290
  static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
  			     const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
291
292
293
  {
  	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...
294
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
295
296
297
  }
  
  /* Print out the per-protocol part of the tuple. */
824f1fbee   Joe Perches   netfilter: Conver...
298
299
  static void tcp_print_tuple(struct seq_file *s,
  			    const struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
300
  {
824f1fbee   Joe Perches   netfilter: Conver...
301
302
303
  	seq_printf(s, "sport=%hu dport=%hu ",
  		   ntohs(tuple->src.u.tcp.port),
  		   ntohs(tuple->dst.u.tcp.port));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
304
305
306
  }
  
  /* Print out the private part of the conntrack. */
37246a583   Steven Rostedt (Red Hat)   netfilter: Remove...
307
  static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
308
  {
a163f2cb3   Florian Westphal   netfilter: conntr...
309
  	seq_printf(s, "%s ", tcp_conntrack_names[ct->proto.tcp.state]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
310
311
312
313
314
315
316
317
318
319
320
321
322
  }
  
  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 ...
323

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

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
327
328
329
330
     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 ...
331
  	td_maxend = max(sack + max(win,1)) seen in reply packets
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
332
333
334
335
  	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 ...
336

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
337
338
     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...
339
340
     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 ...
341

84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
342
343
     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 ...
344

84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
345
     The upper bound limit for a valid (s)ack is not ignored -
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
346
     we doesn't have to deal with fragments.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
347
348
349
350
351
  */
  
  static inline __u32 segment_seq_plus_len(__u32 seq,
  					 size_t len,
  					 unsigned int dataoff,
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
352
  					 const struct tcphdr *tcph)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
353
354
355
356
357
358
  {
  	/* 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 ...
359

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

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
366
367
368
369
370
  /*
   * 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_{...
371
  			const struct tcphdr *tcph,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
372
373
374
  			struct ip_ct_tcp_state *state)
  {
  	unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
375
  	const unsigned char *ptr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
376
377
378
379
380
381
382
383
  	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 ...
384
  	state->td_scale =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
385
386
387
388
389
390
391
392
393
394
395
396
397
  	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:
644c7e48c   Jozsef Kadlecsik   netfilter: nf_con...
398
399
  			if (length < 2)
  				return;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
400
401
402
403
  			opsize=*ptr++;
  			if (opsize < 2) /* "silly options" */
  				return;
  			if (opsize > length)
4a5cc84ae   Jozsef Kadlecsik   netfilter: nf_ct_...
404
  				return;	/* don't parse partial options */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
405

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
406
  			if (opcode == TCPOPT_SACK_PERM
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
407
408
409
410
411
  			    && 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;
122868b37   Gao Feng   netfilter: tcp: U...
412
413
  				if (state->td_scale > TCP_MAX_WSCALE)
  					state->td_scale = TCP_MAX_WSCALE;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
414
415
416
417
418
419
420
421
422
423
  				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_{...
424
                       const struct tcphdr *tcph, __u32 *sack)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
425
  {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
426
  	unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
427
  	const unsigned char *ptr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
428
429
430
431
432
433
434
435
436
437
438
  	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_...
439
  	if (length == TCPOLEN_TSTAMP_ALIGNED
8f05ce91c   YOSHIFUJI Hideaki   [NET] NETFILTER: ...
440
441
442
443
  	    && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
  				       | (TCPOPT_NOP << 16)
  				       | (TCPOPT_TIMESTAMP << 8)
  				       | TCPOLEN_TIMESTAMP))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
444
445
446
447
448
449
450
451
452
453
454
455
456
  		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:
644c7e48c   Jozsef Kadlecsik   netfilter: nf_con...
457
458
  			if (length < 2)
  				return;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
459
460
461
462
  			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;
  		}
  	}
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
485
486
487
488
489
490
491
  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...
492
  			  u_int8_t pf)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
493
  {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
494
  	struct net *net = nf_ct_net(ct);
d2ba1fde4   Gao feng   netfilter: nf_ct_...
495
  	struct nf_tcp_net *tn = tcp_pernet(net);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
496
497
  	struct ip_ct_tcp_state *sender = &state->seen[dir];
  	struct ip_ct_tcp_state *receiver = &state->seen[!dir];
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
498
  	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
499
  	__u32 seq, ack, sack, end, win, swin;
2d89c68ac   Patrick McHardy   netfilter: nf_nat...
500
  	s32 receiver_offset;
356d7d88e   Yuchung Cheng   netfilter: nf_con...
501
  	bool res, in_recv_win;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
502
503
504
505
506
507
508
509
510
511
512
  
  	/*
  	 * 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...
513
  	/* Take into account NAT sequence number mangling */
41d73ec05   Patrick McHardy   netfilter: nf_con...
514
  	receiver_offset = nf_ct_seq_offset(ct, !dir, ack - 1);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
515
516
  	ack -= receiver_offset;
  	sack -= receiver_offset;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
517
518
519
  	pr_debug("tcp_in_window: START
  ");
  	pr_debug("tcp_in_window: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
520
  	nf_ct_dump_tuple(tuple);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
521
522
523
  	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...
524
525
526
527
528
529
530
  	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 ...
531

874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
532
  	if (sender->td_maxwin == 0) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
533
534
535
  		/*
  		 * Initialize sender data.
  		 */
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
536
  		if (tcph->syn) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
537
  			/*
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
538
539
  			 * SYN-ACK in reply to a SYN
  			 * or SYN from reply direction in simultaneous open.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
540
  			 */
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
541
  			sender->td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
542
543
544
545
  			sender->td_maxend = end;
  			sender->td_maxwin = (win == 0 ? 1 : win);
  
  			tcp_options(skb, dataoff, tcph, sender);
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
546
  			/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
547
548
549
550
551
552
  			 * 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 ...
553
  				sender->td_scale =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
554
  				receiver->td_scale = 0;
874ab9233   Jozsef Kadlecsik   netfilter: nf_ct_...
555
556
557
  			if (!tcph->ack)
  				/* Simultaneous open */
  				return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
558
559
560
561
562
  		} 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 ...
563
  			 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
564
  			sender->td_end = end;
6ee0b693b   Changli Gao   netfilter: nf_ct_...
565
566
  			swin = win << sender->td_scale;
  			sender->td_maxwin = (swin == 0 ? 1 : swin);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
567
  			sender->td_maxend = end + sender->td_maxwin;
fac42a9a9   Pablo Neira Ayuso   netfilter: nf_ct_...
568
569
570
571
572
573
574
  			/*
  			 * 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 ...
575
576
577
578
579
580
581
582
  		}
  	} 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 ...
583
  		 * not wait at all; it must only be sure to use sequence
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  		 * 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 ...
598
599
  	} else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
  		    (TCP_FLAG_ACK|TCP_FLAG_RST))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
600
601
602
603
604
605
606
  		   && (ack == 0)) {
  		/*
  		 * Broken TCP stacks, that set ACK in RST packets as well
  		 * with zero ack value.
  		 */
  		ack = sack = receiver->td_end;
  	}
4a70bbfae   Jozsef Kadlecsik   netfilter: Valida...
607
  	if (tcph->rst && seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
608
  		/*
4a70bbfae   Jozsef Kadlecsik   netfilter: Valida...
609
  		 * RST sent answering SYN.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
610
611
  		 */
  		seq = end = sender->td_end;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
612
  	pr_debug("tcp_in_window: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
613
  	nf_ct_dump_tuple(tuple);
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
614
615
616
  	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...
617
618
619
620
621
622
623
  	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);
356d7d88e   Yuchung Cheng   netfilter: nf_con...
624
625
626
  	/* Is the ending sequence in the receive window (if available)? */
  	in_recv_win = !receiver->td_maxwin ||
  		      after(end, sender->td_end - receiver->td_maxwin - 1);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
627
628
629
  	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i
  ",
  		 before(seq, sender->td_maxend + 1),
356d7d88e   Yuchung Cheng   netfilter: nf_con...
630
  		 (in_recv_win ? 1 : 0),
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
631
  		 before(sack, receiver->td_end + 1),
84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
632
  		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
633

a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
634
  	if (before(seq, sender->td_maxend + 1) &&
356d7d88e   Yuchung Cheng   netfilter: nf_con...
635
  	    in_recv_win &&
a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
636
  	    before(sack, receiver->td_end + 1) &&
84ebe1cda   Jozsef Kadlecsik   netfilter: nf_con...
637
  	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
638
  		/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
639
640
641
642
643
644
645
646
647
648
649
  		 * 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...
650
  		if (after(end, sender->td_end)) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
651
  			sender->td_end = end;
ae375044d   Patrick McHardy   netfilter: nf_con...
652
653
  			sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
  		}
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
654
655
656
657
658
659
660
  		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 ...
661
662
663
  		/*
  		 * Update receiver data.
  		 */
fac42a9a9   Pablo Neira Ayuso   netfilter: nf_ct_...
664
  		if (receiver->td_maxwin != 0 && after(end, sender->td_maxend))
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
665
666
667
668
669
670
  			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...
671
672
  		if (ack == receiver->td_end)
  			receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
673

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
674
  		/*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
675
676
677
678
679
680
  		 * 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 ...
681
682
  			    && state->last_end == end
  			    && state->last_win == win)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
683
684
685
686
687
688
  				state->retrans++;
  			else {
  				state->last_dir = dir;
  				state->last_seq = seq;
  				state->last_ack = ack;
  				state->last_end = end;
c1fe3ca51   George Hansper   [NETFILTER]: TCP ...
689
  				state->last_win = win;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
690
691
692
  				state->retrans = 0;
  			}
  		}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
693
  		res = true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
694
  	} else {
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
695
  		res = false;
a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
696
  		if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
d2ba1fde4   Gao feng   netfilter: nf_ct_...
697
  		    tn->tcp_be_liberal)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
698
  			res = true;
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
699
  		if (!res && LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
700
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
701
702
  			"nf_ct_tcp: %s ",
  			before(seq, sender->td_maxend + 1) ?
356d7d88e   Yuchung Cheng   netfilter: nf_con...
703
  			in_recv_win ?
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
704
  			before(sack, receiver->td_end + 1) ?
f9dd09c7f   Jozsef Kadlecsik   netfilter: nf_nat...
705
  			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
706
707
708
709
  			: "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 ...
710
  	}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
711
  	pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
712
713
714
715
  		 "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 ...
716
717
718
  
  	return res;
  }
5c8ce7c92   Willy Tarreau   [NETFILTER]: TCP ...
719
  /* table of valid flag combinations - PUSH, ECE and CWR are always valid */
a3433f35a   Changli Gao   tcp: unify tcp fl...
720
721
  static const u8 tcp_valid_flags[(TCPHDR_FIN|TCPHDR_SYN|TCPHDR_RST|TCPHDR_ACK|
  				 TCPHDR_URG) + 1] =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
722
  {
a3433f35a   Changli Gao   tcp: unify tcp fl...
723
724
725
726
727
728
729
730
731
  	[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 ...
732
733
734
  };
  
  /* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c.  */
8fea97ec1   Patrick McHardy   netfilter: nf_con...
735
  static int tcp_error(struct net *net, struct nf_conn *tmpl,
74c51a149   Alexey Dobriyan   netfilter: netns ...
736
  		     struct sk_buff *skb,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
737
  		     unsigned int dataoff,
76108cea0   Jan Engelhardt   netfilter: Use un...
738
  		     u_int8_t pf,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
739
  		     unsigned int hooknum)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
740
  {
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
741
742
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
743
744
745
746
747
748
  	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 ...
749
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
750
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
751
752
  				"nf_ct_tcp: short packet ");
  		return -NF_ACCEPT;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
753
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
754
755
  	/* Not whole TCP header or malformed packet */
  	if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
756
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
757
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
758
759
760
  				"nf_ct_tcp: truncated/malformed packet ");
  		return -NF_ACCEPT;
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
761

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
762
763
  	/* Checksum invalid? Ignore.
  	 * We skip checking packets on the outgoing path
84fa7933a   Patrick McHardy   [NET]: Replace CH...
764
  	 * because the checksum is assumed to be correct.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
765
766
  	 */
  	/* FIXME: Source route IP option packets --RR */
c04d05529   Alexey Dobriyan   netfilter: netns ...
767
  	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
768
  	    nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
769
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
770
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
771
772
773
774
775
  				  "nf_ct_tcp: bad TCP checksum ");
  		return -NF_ACCEPT;
  	}
  
  	/* Check TCP flags. */
a3433f35a   Changli Gao   tcp: unify tcp fl...
776
  	tcpflags = (tcp_flag_byte(th) & ~(TCPHDR_ECE|TCPHDR_CWR|TCPHDR_PSH));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
777
  	if (!tcp_valid_flags[tcpflags]) {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
778
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
779
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
780
781
782
783
784
785
  				  "nf_ct_tcp: invalid TCP flag combination ");
  		return -NF_ACCEPT;
  	}
  
  	return NF_ACCEPT;
  }
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
786
787
  static unsigned int *tcp_get_timeouts(struct net *net)
  {
be0593c67   Pablo Neira Ayuso   netfilter: nf_ct_...
788
  	return tcp_pernet(net)->timeouts;
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
789
  }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
790
  /* Returns verdict for packet, or -1 for invalid. */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
791
  static int tcp_packet(struct nf_conn *ct,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
792
793
794
  		      const struct sk_buff *skb,
  		      unsigned int dataoff,
  		      enum ip_conntrack_info ctinfo,
76108cea0   Jan Engelhardt   netfilter: Use un...
795
  		      u_int8_t pf,
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
796
797
  		      unsigned int hooknum,
  		      unsigned int *timeouts)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
798
  {
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
799
  	struct net *net = nf_ct_net(ct);
d2ba1fde4   Gao feng   netfilter: nf_ct_...
800
  	struct nf_tcp_net *tn = tcp_pernet(net);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
801
  	struct nf_conntrack_tuple *tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
802
803
  	enum tcp_conntrack new_state, old_state;
  	enum ip_conntrack_dir dir;
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
804
805
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
806
807
808
809
810
  	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...
811
  	spin_lock_bh(&ct->lock);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
812
  	old_state = ct->proto.tcp.state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
813
814
815
  	dir = CTINFO2DIR(ctinfo);
  	index = get_conntrack_index(th);
  	new_state = tcp_conntracks[dir][index][old_state];
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
816
  	tuple = &ct->tuplehash[dir].tuple;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
817
818
  
  	switch (new_state) {
17311393f   Jozsef Kadlecsik   [NETFILTER]: nf_c...
819
820
821
  	case TCP_CONNTRACK_SYN_SENT:
  		if (old_state < TCP_CONNTRACK_TIME_WAIT)
  			break;
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
  		/* 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...
837
838
  		    || (ct->proto.tcp.last_dir == dir
  		        && ct->proto.tcp.last_index == TCP_RST_SET)) {
bc34b8415   Jozsef Kadlecsik   [NETFILTER]: nf_c...
839
840
  			/* Attempt to reopen a closed/aborted connection.
  			 * Delete this connection and look up again. */
440f0d588   Patrick McHardy   netfilter: nf_con...
841
  			spin_unlock_bh(&ct->lock);
2aec609fb   David S. Miller   Merge branch 'mas...
842

6b69fe0c7   Patrick McHardy   netfilter: nf_con...
843
844
845
846
  			/* 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...
847
  			if (nf_ct_kill(ct))
6b69fe0c7   Patrick McHardy   netfilter: nf_con...
848
  				return -NF_REPEAT;
ec8d54096   Christoph Paasch   netfilter: conntr...
849
  			return NF_DROP;
17311393f   Jozsef Kadlecsik   [NETFILTER]: nf_c...
850
851
  		}
  		/* Fall through */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
852
  	case TCP_CONNTRACK_IGNORE:
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
853
854
  		/* Ignored packets:
  		 *
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
855
856
857
858
  		 * 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...
859
860
  		 * a) SYN in ORIGINAL
  		 * b) SYN/ACK in REPLY
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
861
  		 * c) ACK in reply direction after initial SYN in original.
b2155e7f7   Jozsef Kadlecsik   [NETFILTER]: nf_c...
862
863
864
  		 *
  		 * If the ignored packet is invalid, the receiver will send
  		 * a RST we'll catch below.
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
865
  		 */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
866
  		if (index == TCP_SYNACK_SET
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
867
868
869
  		    && 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...
870
  			/* b) This SYN/ACK acknowledges a SYN that we earlier
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
871
872
  			 * 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_...
873
874
  			 * not. We get in sync from the previously annotated
  			 * values.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
875
  			 */
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
876
877
878
879
880
881
882
883
884
885
886
  			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;
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
887
  			ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
888
889
890
891
892
  			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 ...
893
  		}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
894
895
896
897
  		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 ...
898
  		    segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
899
900
901
902
903
904
  		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
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
905
906
907
  		 * then we'll get in sync. Otherwise, the server potentially
  		 * responds with a challenge ACK if implementing RFC5961.
  		 */
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
  		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;
  			}
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
923
924
925
926
927
928
929
  			/* Mark the potential for RFC5961 challenge ACK,
  			 * this pose a special problem for LAST_ACK state
  			 * as ACK is intrepretated as ACKing last FIN.
  			 */
  			if (old_state == TCP_CONNTRACK_LAST_ACK)
  				ct->proto.tcp.last_flags |=
  					IP_CT_EXP_CHALLENGE_ACK;
c4832c7bb   Pablo Neira Ayuso   netfilter: nf_ct_...
930
  		}
440f0d588   Patrick McHardy   netfilter: nf_con...
931
  		spin_unlock_bh(&ct->lock);
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
932
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
933
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
1a4ac9870   Pablo Neira Ayuso   netfilter: nf_ct_...
934
935
  				  "nf_ct_tcp: invalid packet ignored in "
  				  "state %s ", tcp_conntrack_names[old_state]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
936
937
  		return NF_ACCEPT;
  	case TCP_CONNTRACK_MAX:
48b1de4c1   Patrick McHardy   netfilter: add SY...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
  		/* Special case for SYN proxy: when the SYN to the server or
  		 * the SYN/ACK from the server is lost, the client may transmit
  		 * a keep-alive packet while in SYN_SENT state. This needs to
  		 * be associated with the original conntrack entry in order to
  		 * generate a new SYN with the correct sequence number.
  		 */
  		if (nfct_synproxy(ct) && old_state == TCP_CONNTRACK_SYN_SENT &&
  		    index == TCP_ACK_SET && dir == IP_CT_DIR_ORIGINAL &&
  		    ct->proto.tcp.last_dir == IP_CT_DIR_ORIGINAL &&
  		    ct->proto.tcp.seen[dir].td_end - 1 == ntohl(th->seq)) {
  			pr_debug("nf_ct_tcp: SYN proxy client keep alive
  ");
  			spin_unlock_bh(&ct->lock);
  			return NF_ACCEPT;
  		}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
953
  		/* Invalid packet */
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
954
955
956
  		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...
957
  		spin_unlock_bh(&ct->lock);
c2a2c7e0c   Alexey Dobriyan   netfilter: netns ...
958
  		if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
959
  			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
960
961
  				  "nf_ct_tcp: invalid state ");
  		return -NF_ACCEPT;
b3cad287d   Jesper Dangaard Brouer   conntrack: RFC596...
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
  	case TCP_CONNTRACK_TIME_WAIT:
  		/* RFC5961 compliance cause stack to send "challenge-ACK"
  		 * e.g. in response to spurious SYNs.  Conntrack MUST
  		 * not believe this ACK is acking last FIN.
  		 */
  		if (old_state == TCP_CONNTRACK_LAST_ACK &&
  		    index == TCP_ACK_SET &&
  		    ct->proto.tcp.last_dir != dir &&
  		    ct->proto.tcp.last_index == TCP_SYN_SET &&
  		    (ct->proto.tcp.last_flags & IP_CT_EXP_CHALLENGE_ACK)) {
  			/* Detected RFC5961 challenge ACK */
  			ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
  			spin_unlock_bh(&ct->lock);
  			if (LOG_INVALID(net, IPPROTO_TCP))
  				nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
  				      "nf_ct_tcp: challenge-ACK ignored ");
  			return NF_ACCEPT; /* Don't change state */
  		}
  		break;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
981
982
  	case TCP_CONNTRACK_CLOSE:
  		if (index == TCP_RST_SET
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
983
984
985
  		    && (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_...
986
  			spin_unlock_bh(&ct->lock);
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
987
  			if (LOG_INVALID(net, IPPROTO_TCP))
30e0c6a6b   Gao feng   netfilter: nf_log...
988
989
  				nf_log_packet(net, pf, 0, skb, NULL, NULL,
  					      NULL, "nf_ct_tcp: invalid RST ");
bfcaa5027   Jozsef Kadlecsik   netfilter: nf_ct_...
990
991
992
  			return -NF_ACCEPT;
  		}
  		if (index == TCP_RST_SET
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
993
994
995
996
997
  		    && ((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...
998
  			/* RST sent to invalid SYN or ACK we had let through
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
999
1000
1001
1002
1003
1004
  			 * 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 ...
1005
  			 * We skip window checking, because packet might ACK
73f306024   Jozsef Kadlecsik   [NETFILTER]: Igno...
1006
  			 * segments we ignored. */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1007
1008
  			goto in_window;
  		}
93b1fae49   Adrian Bunk   spelling: s/troug...
1009
  		/* Just fall through */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1010
1011
1012
1013
  	default:
  		/* Keep compilers happy. */
  		break;
  	}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1014
  	if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1015
  			   skb, dataoff, th, pf)) {
440f0d588   Patrick McHardy   netfilter: nf_con...
1016
  		spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1017
1018
1019
1020
  		return -NF_ACCEPT;
  	}
       in_window:
  	/* From now on we have got in-window packets */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1021
1022
  	ct->proto.tcp.last_index = index;
  	ct->proto.tcp.last_dir = dir;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1023

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1024
  	pr_debug("tcp_conntracks: ");
3c9fba656   Jan Engelhardt   [NETFILTER]: nf_c...
1025
  	nf_ct_dump_tuple(tuple);
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1026
1027
1028
1029
1030
  	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 ...
1031

c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1032
  	ct->proto.tcp.state = new_state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1033
  	if (old_state != new_state
d0c1fd7a8   Jozsef Kadlecsik   [NETFILTER] nf_co...
1034
  	    && new_state == TCP_CONNTRACK_FIN_WAIT)
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1035
  		ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
ae375044d   Patrick McHardy   netfilter: nf_con...
1036

d2ba1fde4   Gao feng   netfilter: nf_ct_...
1037
  	if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1038
1039
  	    timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
  		timeout = timeouts[TCP_CONNTRACK_RETRANS];
ae375044d   Patrick McHardy   netfilter: nf_con...
1040
1041
  	else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
  		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1042
1043
  		 timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
  		timeout = timeouts[TCP_CONNTRACK_UNACK];
ae375044d   Patrick McHardy   netfilter: nf_con...
1044
  	else
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1045
  		timeout = timeouts[new_state];
440f0d588   Patrick McHardy   netfilter: nf_con...
1046
  	spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1047

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

c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1051
  	if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1052
1053
1054
1055
1056
  		/* 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...
1057
  			nf_ct_kill_acct(ct, ctinfo, skb);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1058
1059
  			return NF_ACCEPT;
  		}
6547a2218   Florian Westphal   netfilter: nf_con...
1060
1061
1062
1063
1064
1065
  		/* ESTABLISHED without SEEN_REPLY, i.e. mid-connection
  		 * pickup with loose=1. Avoid large ESTABLISHED timeout.
  		 */
  		if (new_state == TCP_CONNTRACK_ESTABLISHED &&
  		    timeout > timeouts[TCP_CONNTRACK_UNACK])
  			timeout = timeouts[TCP_CONNTRACK_UNACK];
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1066
  	} else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1067
1068
1069
  		   && (old_state == TCP_CONNTRACK_SYN_RECV
  		       || old_state == TCP_CONNTRACK_ESTABLISHED)
  		   && new_state == TCP_CONNTRACK_ESTABLISHED) {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1070
1071
  		/* 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 ...
1072
  		   connection. */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1073
  		set_bit(IPS_ASSURED_BIT, &ct->status);
858b31330   Patrick McHardy   netfilter: nf_con...
1074
  		nf_conntrack_event_cache(IPCT_ASSURED, ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1075
  	}
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1076
  	nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1077
1078
1079
  
  	return NF_ACCEPT;
  }
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1080

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1081
  /* Called when a new connection for this protocol found. */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1082
  static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1083
  		    unsigned int dataoff, unsigned int *timeouts)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1084
1085
  {
  	enum tcp_conntrack new_state;
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
1086
1087
  	const struct tcphdr *th;
  	struct tcphdr _tcph;
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1088
1089
  	struct net *net = nf_ct_net(ct);
  	struct nf_tcp_net *tn = tcp_pernet(net);
82f568fc2   Jan Engelhardt   [NETFILTER]: nf_{...
1090
1091
  	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 ...
1092
1093
1094
1095
1096
  
  	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...
1097
  	new_state = tcp_conntracks[0][get_conntrack_index(th)][TCP_CONNTRACK_NONE];
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1098
1099
1100
  
  	/* Invalid: delete conntrack */
  	if (new_state >= TCP_CONNTRACK_MAX) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1101
1102
  		pr_debug("nf_ct_tcp: invalid new deleting.
  ");
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1103
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1104
1105
1106
  	}
  
  	if (new_state == TCP_CONNTRACK_SYN_SENT) {
e5fc9e7a6   Changli Gao   netfilter: nf_con...
1107
  		memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1108
  		/* SYN packet */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1109
  		ct->proto.tcp.seen[0].td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1110
1111
  			segment_seq_plus_len(ntohl(th->seq), skb->len,
  					     dataoff, th);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1112
1113
1114
1115
1116
1117
1118
  		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]);
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1119
  	} else if (tn->tcp_loose == 0) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1120
  		/* Don't try to pick up connections. */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
1121
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1122
  	} else {
e5fc9e7a6   Changli Gao   netfilter: nf_con...
1123
  		memset(&ct->proto.tcp, 0, sizeof(ct->proto.tcp));
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1124
1125
1126
1127
1128
  		/*
  		 * 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...
1129
  		ct->proto.tcp.seen[0].td_end =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1130
1131
  			segment_seq_plus_len(ntohl(th->seq), skb->len,
  					     dataoff, th);
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1132
1133
1134
1135
1136
1137
  		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 ...
1138

a09113c2c   Patrick McHardy   [NETFILTER]: tcp ...
1139
1140
  		/* We assume SACK and liberal window checking to handle
  		 * window scaling */
c88130bcd   Patrick McHardy   [NETFILTER]: nf_c...
1141
1142
1143
  		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 ...
1144
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1145

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

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
1149
1150
1151
1152
1153
1154
1155
  	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...
1156
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1157
  }
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1158

c6dd940b1   Florian Westphal   netfilter: allow ...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
  static bool tcp_can_early_drop(const struct nf_conn *ct)
  {
  	switch (ct->proto.tcp.state) {
  	case TCP_CONNTRACK_FIN_WAIT:
  	case TCP_CONNTRACK_LAST_ACK:
  	case TCP_CONNTRACK_TIME_WAIT:
  	case TCP_CONNTRACK_CLOSE:
  	case TCP_CONNTRACK_CLOSE_WAIT:
  		return true;
  	default:
  		break;
  	}
  
  	return false;
  }
c0cd11566   Igor Maravić   net:netfilter: us...
1174
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1175
1176
1177
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_conntrack.h>
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1178
  static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
440f0d588   Patrick McHardy   netfilter: nf_con...
1179
  			 struct nf_conn *ct)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1180
  {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1181
  	struct nlattr *nest_parms;
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1182
  	struct nf_ct_tcp_flags tmp = {};
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1183

440f0d588   Patrick McHardy   netfilter: nf_con...
1184
  	spin_lock_bh(&ct->lock);
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1185
1186
1187
  	nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
  	if (!nest_parms)
  		goto nla_put_failure;
4925a459e   David S. Miller   nf_conntrack_prot...
1188
1189
1190
1191
1192
1193
  	if (nla_put_u8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state) ||
  	    nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
  		       ct->proto.tcp.seen[0].td_scale) ||
  	    nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
  		       ct->proto.tcp.seen[1].td_scale))
  		goto nla_put_failure;
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1194
1195
  
  	tmp.flags = ct->proto.tcp.seen[0].flags;
4925a459e   David S. Miller   nf_conntrack_prot...
1196
1197
1198
  	if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
  		    sizeof(struct nf_ct_tcp_flags), &tmp))
  		goto nla_put_failure;
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1199
1200
  
  	tmp.flags = ct->proto.tcp.seen[1].flags;
4925a459e   David S. Miller   nf_conntrack_prot...
1201
1202
1203
  	if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
  		    sizeof(struct nf_ct_tcp_flags), &tmp))
  		goto nla_put_failure;
440f0d588   Patrick McHardy   netfilter: nf_con...
1204
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1205

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1206
  	nla_nest_end(skb, nest_parms);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1207
1208
  
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1209
  nla_put_failure:
440f0d588   Patrick McHardy   netfilter: nf_con...
1210
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1211
1212
  	return -1;
  }
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1213
1214
1215
1216
1217
1218
  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 ...
1219
  };
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1220
  static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1221
  {
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
1222
  	struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1223
  	struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1224
  	int err;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1225
1226
1227
  
  	/* updates could not contain anything about the private
  	 * protocol info, in that case skip the parsing */
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
1228
  	if (!pattr)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1229
  		return 0;
fceb6435e   Johannes Berg   netlink: pass ext...
1230
1231
  	err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr,
  			       tcp_nla_policy, NULL);
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1232
1233
  	if (err < 0)
  		return err;
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1234

5f7da4d26   Patrick McHardy   [NETFILTER]: nf_c...
1235
1236
  	if (tb[CTA_PROTOINFO_TCP_STATE] &&
  	    nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX)
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1237
  		return -EINVAL;
440f0d588   Patrick McHardy   netfilter: nf_con...
1238
  	spin_lock_bh(&ct->lock);
5f7da4d26   Patrick McHardy   [NETFILTER]: nf_c...
1239
1240
  	if (tb[CTA_PROTOINFO_TCP_STATE])
  		ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1241

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1242
  	if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1243
  		struct nf_ct_tcp_flags *attr =
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1244
  			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1245
1246
1247
  		ct->proto.tcp.seen[0].flags &= ~attr->mask;
  		ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1248
  	if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1249
  		struct nf_ct_tcp_flags *attr =
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1250
  			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1251
1252
1253
  		ct->proto.tcp.seen[1].flags &= ~attr->mask;
  		ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
1254
1255
  	if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&
  	    tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
c8e2078cf   Pablo Neira Ayuso   [NETFILTER]: ctne...
1256
1257
  	    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...
1258
1259
1260
1261
  		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...
1262
  	}
440f0d588   Patrick McHardy   netfilter: nf_con...
1263
  	spin_unlock_bh(&ct->lock);
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1264
1265
1266
  
  	return 0;
  }
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  
  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 ...
1278
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1279

509784623   Pablo Neira Ayuso   netfilter: add ct...
1280
1281
1282
1283
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_cttimeout.h>
8264deb81   Gao feng   netfilter: nf_con...
1284
1285
  static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
  				     struct net *net, void *data)
509784623   Pablo Neira Ayuso   netfilter: add ct...
1286
1287
  {
  	unsigned int *timeouts = data;
8264deb81   Gao feng   netfilter: nf_con...
1288
  	struct nf_tcp_net *tn = tcp_pernet(net);
509784623   Pablo Neira Ayuso   netfilter: add ct...
1289
1290
1291
1292
  	int i;
  
  	/* set default TCP timeouts. */
  	for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++)
8264deb81   Gao feng   netfilter: nf_con...
1293
  		timeouts[i] = tn->timeouts[i];
509784623   Pablo Neira Ayuso   netfilter: add ct...
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  
  	if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) {
  		timeouts[TCP_CONNTRACK_SYN_SENT] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_SYN_RECV]) {
  		timeouts[TCP_CONNTRACK_SYN_RECV] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_RECV]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_ESTABLISHED]) {
  		timeouts[TCP_CONNTRACK_ESTABLISHED] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_ESTABLISHED]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_FIN_WAIT]) {
  		timeouts[TCP_CONNTRACK_FIN_WAIT] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_FIN_WAIT]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]) {
  		timeouts[TCP_CONNTRACK_CLOSE_WAIT] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_LAST_ACK]) {
  		timeouts[TCP_CONNTRACK_LAST_ACK] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_LAST_ACK]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_TIME_WAIT]) {
  		timeouts[TCP_CONNTRACK_TIME_WAIT] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_TIME_WAIT]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_CLOSE]) {
  		timeouts[TCP_CONNTRACK_CLOSE] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_SYN_SENT2]) {
  		timeouts[TCP_CONNTRACK_SYN_SENT2] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT2]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_RETRANS]) {
  		timeouts[TCP_CONNTRACK_RETRANS] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_RETRANS]))*HZ;
  	}
  	if (tb[CTA_TIMEOUT_TCP_UNACK]) {
  		timeouts[TCP_CONNTRACK_UNACK] =
  			ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_UNACK]))*HZ;
  	}
  	return 0;
  }
  
  static int
  tcp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
  {
  	const unsigned int *timeouts = data;
4925a459e   David S. Miller   nf_conntrack_prot...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
  	if (nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT,
  			htonl(timeouts[TCP_CONNTRACK_SYN_SENT] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_RECV,
  			 htonl(timeouts[TCP_CONNTRACK_SYN_RECV] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_ESTABLISHED,
  			 htonl(timeouts[TCP_CONNTRACK_ESTABLISHED] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_FIN_WAIT,
  			 htonl(timeouts[TCP_CONNTRACK_FIN_WAIT] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE_WAIT,
  			 htonl(timeouts[TCP_CONNTRACK_CLOSE_WAIT] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_LAST_ACK,
  			 htonl(timeouts[TCP_CONNTRACK_LAST_ACK] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_TIME_WAIT,
  			 htonl(timeouts[TCP_CONNTRACK_TIME_WAIT] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE,
  			 htonl(timeouts[TCP_CONNTRACK_CLOSE] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT2,
  			 htonl(timeouts[TCP_CONNTRACK_SYN_SENT2] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_RETRANS,
  			 htonl(timeouts[TCP_CONNTRACK_RETRANS] / HZ)) ||
  	    nla_put_be32(skb, CTA_TIMEOUT_TCP_UNACK,
  			 htonl(timeouts[TCP_CONNTRACK_UNACK] / HZ)))
  		goto nla_put_failure;
509784623   Pablo Neira Ayuso   netfilter: add ct...
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
  	return 0;
  
  nla_put_failure:
  	return -ENOSPC;
  }
  
  static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {
  	[CTA_TIMEOUT_TCP_SYN_SENT]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_SYN_RECV]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_ESTABLISHED]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_FIN_WAIT]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_CLOSE_WAIT]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_LAST_ACK]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_TIME_WAIT]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_CLOSE]		= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_SYN_SENT2]	= { .type = NLA_U32 },
6d1fafcae   Florian Westphal   netfilter: ctnetl...
1385
1386
  	[CTA_TIMEOUT_TCP_RETRANS]	= { .type = NLA_U32 },
  	[CTA_TIMEOUT_TCP_UNACK]		= { .type = NLA_U32 },
509784623   Pablo Neira Ayuso   netfilter: add ct...
1387
1388
  };
  #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1389
  #ifdef CONFIG_SYSCTL
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1390
1391
  static struct ctl_table tcp_sysctl_table[] = {
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1392
  		.procname	= "nf_conntrack_tcp_timeout_syn_sent",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1393
1394
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1395
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1396
1397
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1398
  		.procname	= "nf_conntrack_tcp_timeout_syn_recv",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1399
1400
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1401
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1402
1403
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1404
  		.procname	= "nf_conntrack_tcp_timeout_established",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1405
1406
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1407
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1408
1409
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1410
  		.procname	= "nf_conntrack_tcp_timeout_fin_wait",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1411
1412
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1413
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1414
1415
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1416
  		.procname	= "nf_conntrack_tcp_timeout_close_wait",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1417
1418
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1419
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1420
1421
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1422
  		.procname	= "nf_conntrack_tcp_timeout_last_ack",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1423
1424
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1425
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1426
1427
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1428
  		.procname	= "nf_conntrack_tcp_timeout_time_wait",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1429
1430
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1431
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1432
1433
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1434
  		.procname	= "nf_conntrack_tcp_timeout_close",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1435
1436
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1437
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1438
1439
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1440
  		.procname	= "nf_conntrack_tcp_timeout_max_retrans",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1441
1442
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1443
  		.proc_handler	= proc_dointvec_jiffies,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1444
1445
  	},
  	{
ae375044d   Patrick McHardy   netfilter: nf_con...
1446
  		.procname	= "nf_conntrack_tcp_timeout_unacknowledged",
ae375044d   Patrick McHardy   netfilter: nf_con...
1447
1448
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1449
  		.proc_handler	= proc_dointvec_jiffies,
ae375044d   Patrick McHardy   netfilter: nf_con...
1450
1451
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1452
  		.procname	= "nf_conntrack_tcp_loose",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1453
1454
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1455
  		.proc_handler	= proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1456
1457
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1458
  		.procname       = "nf_conntrack_tcp_be_liberal",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1459
1460
  		.maxlen         = sizeof(unsigned int),
  		.mode           = 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1461
  		.proc_handler   = proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1462
1463
  	},
  	{
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1464
  		.procname	= "nf_conntrack_tcp_max_retrans",
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1465
1466
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
1467
  		.proc_handler	= proc_dointvec,
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1468
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
1469
  	{ }
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
1470
1471
  };
  #endif /* CONFIG_SYSCTL */
efa758fe2   Gao feng   netfilter: nf_ct_...
1472
1473
  static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn,
  				    struct nf_tcp_net *tn)
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1474
1475
  {
  #ifdef CONFIG_SYSCTL
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
  	if (pn->ctl_table)
  		return 0;
  
  	pn->ctl_table = kmemdup(tcp_sysctl_table,
  				sizeof(tcp_sysctl_table),
  				GFP_KERNEL);
  	if (!pn->ctl_table)
  		return -ENOMEM;
  
  	pn->ctl_table[0].data = &tn->timeouts[TCP_CONNTRACK_SYN_SENT];
  	pn->ctl_table[1].data = &tn->timeouts[TCP_CONNTRACK_SYN_RECV];
  	pn->ctl_table[2].data = &tn->timeouts[TCP_CONNTRACK_ESTABLISHED];
  	pn->ctl_table[3].data = &tn->timeouts[TCP_CONNTRACK_FIN_WAIT];
  	pn->ctl_table[4].data = &tn->timeouts[TCP_CONNTRACK_CLOSE_WAIT];
  	pn->ctl_table[5].data = &tn->timeouts[TCP_CONNTRACK_LAST_ACK];
  	pn->ctl_table[6].data = &tn->timeouts[TCP_CONNTRACK_TIME_WAIT];
  	pn->ctl_table[7].data = &tn->timeouts[TCP_CONNTRACK_CLOSE];
  	pn->ctl_table[8].data = &tn->timeouts[TCP_CONNTRACK_RETRANS];
  	pn->ctl_table[9].data = &tn->timeouts[TCP_CONNTRACK_UNACK];
  	pn->ctl_table[10].data = &tn->tcp_loose;
  	pn->ctl_table[11].data = &tn->tcp_be_liberal;
  	pn->ctl_table[12].data = &tn->tcp_max_retrans;
  #endif
  	return 0;
  }
efa758fe2   Gao feng   netfilter: nf_ct_...
1501
  static int tcp_init_net(struct net *net, u_int16_t proto)
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1502
  {
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1503
  	struct nf_tcp_net *tn = tcp_pernet(net);
efa758fe2   Gao feng   netfilter: nf_ct_...
1504
1505
1506
1507
  	struct nf_proto_net *pn = &tn->pn;
  
  	if (!pn->users) {
  		int i;
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1508

d2ba1fde4   Gao feng   netfilter: nf_ct_...
1509
1510
1511
1512
1513
1514
1515
  		for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
  			tn->timeouts[i] = tcp_timeouts[i];
  
  		tn->tcp_loose = nf_ct_tcp_loose;
  		tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
  		tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
  	}
adf051684   Pablo Neira Ayuso   netfilter: remove...
1516
  	return tcp_kmemdup_sysctl_table(pn, tn);
d2ba1fde4   Gao feng   netfilter: nf_ct_...
1517
  }
08911475d   Pablo Neira Ayuso   netfilter: nf_con...
1518
1519
1520
1521
  static struct nf_proto_net *tcp_get_net_proto(struct net *net)
  {
  	return &net->ct.nf_ct_proto.tcp.pn;
  }
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
1522
  struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1523
1524
  {
  	.l3proto		= PF_INET,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1525
  	.l4proto 		= IPPROTO_TCP,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1526
1527
1528
1529
1530
  	.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,
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1531
  	.get_timeouts		= tcp_get_timeouts,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1532
  	.new 			= tcp_new,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
1533
  	.error			= tcp_error,
c6dd940b1   Florian Westphal   netfilter: allow ...
1534
  	.can_early_drop		= tcp_can_early_drop,
c0cd11566   Igor Maravić   net:netfilter: us...
1535
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1536
  	.to_nlattr		= tcp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1537
  	.nlattr_size		= tcp_nlattr_size,
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1538
1539
1540
  	.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...
1541
  	.nlattr_tuple_size	= tcp_nlattr_tuple_size,
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1542
  	.nla_policy		= nf_ct_port_nla_policy,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1543
  #endif
509784623   Pablo Neira Ayuso   netfilter: add ct...
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  	.ctnl_timeout		= {
  		.nlattr_to_obj	= tcp_timeout_nlattr_to_obj,
  		.obj_to_nlattr	= tcp_timeout_obj_to_nlattr,
  		.nlattr_max	= CTA_TIMEOUT_TCP_MAX,
  		.obj_size	= sizeof(unsigned int) *
  					TCP_CONNTRACK_TIMEOUT_MAX,
  		.nla_policy	= tcp_timeout_nla_policy,
  	},
  #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
efa758fe2   Gao feng   netfilter: nf_ct_...
1554
  	.init_net		= tcp_init_net,
08911475d   Pablo Neira Ayuso   netfilter: nf_con...
1555
  	.get_net_proto		= tcp_get_net_proto,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1556
  };
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1557
  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1558

61075af51   Patrick McHardy   [NETFILTER]: nf_c...
1559
  struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1560
1561
  {
  	.l3proto		= PF_INET6,
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
1562
  	.l4proto 		= IPPROTO_TCP,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1563
1564
1565
1566
1567
  	.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,
2c8503f55   Pablo Neira Ayuso   netfilter: nf_con...
1568
  	.get_timeouts		= tcp_get_timeouts,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1569
  	.new 			= tcp_new,
96f6bf82e   Patrick McHardy   [NETFILTER]: Conv...
1570
  	.error			= tcp_error,
c6dd940b1   Florian Westphal   netfilter: allow ...
1571
  	.can_early_drop		= tcp_can_early_drop,
c0cd11566   Igor Maravić   net:netfilter: us...
1572
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1573
  	.to_nlattr		= tcp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
1574
  	.nlattr_size		= tcp_nlattr_size,
fdf708322   Patrick McHardy   [NETFILTER]: nfne...
1575
1576
1577
  	.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...
1578
  	.nlattr_tuple_size	= tcp_nlattr_tuple_size,
f73e924cd   Patrick McHardy   [NETFILTER]: ctne...
1579
  	.nla_policy		= nf_ct_port_nla_policy,
c1d10adb4   Pablo Neira Ayuso   [NETFILTER]: Add ...
1580
  #endif
509784623   Pablo Neira Ayuso   netfilter: add ct...
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
  	.ctnl_timeout		= {
  		.nlattr_to_obj	= tcp_timeout_nlattr_to_obj,
  		.obj_to_nlattr	= tcp_timeout_obj_to_nlattr,
  		.nlattr_max	= CTA_TIMEOUT_TCP_MAX,
  		.obj_size	= sizeof(unsigned int) *
  					TCP_CONNTRACK_TIMEOUT_MAX,
  		.nla_policy	= tcp_timeout_nla_policy,
  	},
  #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
efa758fe2   Gao feng   netfilter: nf_ct_...
1591
  	.init_net		= tcp_init_net,
08911475d   Pablo Neira Ayuso   netfilter: nf_con...
1592
  	.get_net_proto		= tcp_get_net_proto,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1593
  };
13b183391   Patrick McHardy   [NETFILTER]: nf_c...
1594
  EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);