Blame view

net/sctp/sm_statefuns.c 204 KB
47505b8bc   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
2
  /* SCTP kernel implementation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
   * (C) Copyright IBM Corp. 2001, 2004
   * Copyright (c) 1999-2000 Cisco, Inc.
   * Copyright (c) 1999-2001 Motorola, Inc.
   * Copyright (c) 2001-2002 Intel Corp.
   * Copyright (c) 2002      Nokia Corp.
   *
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
9
   * This is part of the SCTP Linux Kernel Implementation.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
   *
   * These are the state functions for the state machine.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
   * Please send any bug reports or fixes you make to the
   * email address(es):
91705c61b   Daniel Borkmann   net: sctp: trivia...
15
   *    lksctp developers <linux-sctp@vger.kernel.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
22
23
24
25
26
27
28
   * Written or modified by:
   *    La Monte H.P. Yarroll <piggy@acm.org>
   *    Karl Knutson          <karl@athena.chicago.il.us>
   *    Mathew Kotowsky       <kotowsky@sctp.org>
   *    Sridhar Samudrala     <samudrala@us.ibm.com>
   *    Jon Grimm             <jgrimm@us.ibm.com>
   *    Hui Huang 	    <hui.huang@nokia.com>
   *    Dajiang Zhang 	    <dajiang.zhang@nokia.com>
   *    Daisy Chang	    <daisyc@us.ibm.com>
   *    Ardelle Fan	    <ardelle.fan@intel.com>
   *    Ryan Layer	    <rmlayer@us.ibm.com>
   *    Kevin Gao		    <kevin.gao@intel.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
   */
145ce502e   Joe Perches   net/sctp: Use pr_...
30
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/ip.h>
  #include <linux/ipv6.h>
  #include <linux/net.h>
  #include <linux/inet.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
37
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
  #include <net/sock.h>
  #include <net/inet_ecn.h>
  #include <linux/skbuff.h>
  #include <net/sctp/sctp.h>
  #include <net/sctp/sm.h>
  #include <net/sctp/structs.h>
103d750c8   Masami Hiramatsu   net: sctp: Add SC...
44
45
  #define CREATE_TRACE_POINTS
  #include <trace/events/sctp.h>
172a1599b   Xin Long   sctp: remove the ...
46
47
48
49
50
51
  static struct sctp_packet *sctp_abort_pkt_new(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
  					const void *payload, size_t paylen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
  static int sctp_eat_data(const struct sctp_association *asoc,
  			 struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
54
  			 struct sctp_cmd_seq *commands);
172a1599b   Xin Long   sctp: remove the ...
55
56
57
58
  static struct sctp_packet *sctp_ootb_pkt_new(
  					struct net *net,
  					const struct sctp_association *asoc,
  					const struct sctp_chunk *chunk);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
59
60
  static void sctp_send_stale_cookie_err(struct net *net,
  				       const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  				       const struct sctp_association *asoc,
  				       const struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
63
  				       struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  				       struct sctp_chunk *err_chunk);
172a1599b   Xin Long   sctp: remove the ...
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  static enum sctp_disposition sctp_sf_do_5_2_6_stale(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands);
  static enum sctp_disposition sctp_sf_shut_8_4_5(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands);
  static enum sctp_disposition sctp_sf_tabort_8_4_8(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
81
  					const struct sctp_endpoint *ep,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
82
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
83
  					const union sctp_subtype type,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
84
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
85
  					struct sctp_cmd_seq *commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
172a1599b   Xin Long   sctp: remove the ...
87
88
89
90
91
92
  static enum sctp_disposition sctp_stop_t1_and_abort(
  					struct net *net,
  					struct sctp_cmd_seq *commands,
  					__be16 error, int sk_err,
  					const struct sctp_association *asoc,
  					struct sctp_transport *transport);
52c1da395   Adrian Bunk   [PATCH] make vari...
93

172a1599b   Xin Long   sctp: remove the ...
94
95
96
97
98
99
100
101
  static enum sctp_disposition sctp_sf_abort_violation(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					void *arg,
  					struct sctp_cmd_seq *commands,
  					const __u8 *payload,
  					const size_t paylen);
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
102

172a1599b   Xin Long   sctp: remove the ...
103
104
105
106
107
108
109
  static enum sctp_disposition sctp_sf_violation_chunklen(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110

172a1599b   Xin Long   sctp: remove the ...
111
112
113
114
115
116
117
  static enum sctp_disposition sctp_sf_violation_paramlen(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg, void *ext,
  					struct sctp_cmd_seq *commands);
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
118

172a1599b   Xin Long   sctp: remove the ...
119
120
121
122
123
124
125
  static enum sctp_disposition sctp_sf_violation_ctsn(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands);
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
126

172a1599b   Xin Long   sctp: remove the ...
127
128
129
130
131
132
133
  static enum sctp_disposition sctp_sf_violation_chunk(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
134

4785c7ae1   Xin Long   sctp: remove the ...
135
  static enum sctp_ierror sctp_sf_authenticate(
172a1599b   Xin Long   sctp: remove the ...
136
  					const struct sctp_association *asoc,
172a1599b   Xin Long   sctp: remove the ...
137
  					struct sctp_chunk *chunk);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
138

172a1599b   Xin Long   sctp: remove the ...
139
140
  static enum sctp_disposition __sctp_sf_do_9_1_abort(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
141
  					const struct sctp_endpoint *ep,
75205f478   Vlad Yasevich   [SCTP]: Implement...
142
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
143
  					const union sctp_subtype type,
75205f478   Vlad Yasevich   [SCTP]: Implement...
144
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
145
  					struct sctp_cmd_seq *commands);
75205f478   Vlad Yasevich   [SCTP]: Implement...
146

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
  /* Small helper function that checks if the chunk length
   * is of the appropriate length.  The 'required_length' argument
   * is set to be the size of a specific chunk we are testing.
509e7a311   Marcelo Ricardo Leitner   sctp: sctp_chunk_...
150
151
   * Return Values:  true  = Valid length
   * 		   false = Invalid length
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
   *
   */
172a1599b   Xin Long   sctp: remove the ...
154
155
  static inline bool sctp_chunk_length_valid(struct sctp_chunk *chunk,
  					   __u16 required_length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
  {
  	__u16 chunk_length = ntohs(chunk->chunk_hdr->length);
26b87c788   Daniel Borkmann   net: sctp: fix re...
158
159
  	/* Previously already marked? */
  	if (unlikely(chunk->pdiscard))
509e7a311   Marcelo Ricardo Leitner   sctp: sctp_chunk_...
160
  		return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  	if (unlikely(chunk_length < required_length))
509e7a311   Marcelo Ricardo Leitner   sctp: sctp_chunk_...
162
  		return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

509e7a311   Marcelo Ricardo Leitner   sctp: sctp_chunk_...
164
  	return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  }
245709ec8   Xin Long   sctp: move the fo...
166
167
168
169
170
171
172
173
174
  /* Check for format error in an ABORT chunk */
  static inline bool sctp_err_chunk_valid(struct sctp_chunk *chunk)
  {
  	struct sctp_errhdr *err;
  
  	sctp_walk_errors(err, chunk->chunk_hdr);
  
  	return (void *)err == (void *)chunk->chunk_end;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /**********************************************************
   * These are the state functions for handling chunk events.
   **********************************************************/
  
  /*
   * Process the final SHUTDOWN COMPLETE.
   *
   * Section: 4 (C) (diagram), 9.2
   * Upon reception of the SHUTDOWN COMPLETE chunk the endpoint will verify
   * that it is in SHUTDOWN-ACK-SENT state, if it is not the chunk should be
   * discarded. If the endpoint is in the SHUTDOWN-ACK-SENT state the endpoint
   * should stop the T2-shutdown timer and remove all knowledge of the
   * association (and thus the association enters the CLOSED state).
   *
047a2428a   Jerome Forissier   [SCTP] Implement ...
189
   * Verification Tag: 8.5.1(C), sctpimpguide 2.41.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
   * C) Rules for packet carrying SHUTDOWN COMPLETE:
   * ...
047a2428a   Jerome Forissier   [SCTP] Implement ...
192
193
194
195
196
197
198
199
200
   * - The receiver of a SHUTDOWN COMPLETE shall accept the packet
   *   if the Verification Tag field of the packet matches its own tag and
   *   the T bit is not set
   *   OR
   *   it is set to its peer's tag and the T bit is set in the Chunk
   *   Flags.
   *   Otherwise, the receiver MUST silently discard the packet
   *   and take no further action.  An endpoint MUST ignore the
   *   SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
207
208
209
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
210
211
212
213
214
  enum sctp_disposition sctp_sf_do_4_C(struct net *net,
  				     const struct sctp_endpoint *ep,
  				     const struct sctp_association *asoc,
  				     const union sctp_subtype type,
  				     void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
  {
  	struct sctp_chunk *chunk = arg;
  	struct sctp_ulpevent *ev;
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
218
  	if (!sctp_vtag_verify_either(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
219
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
220

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
226
  	/* RFC 2960 6.10 Bundling
  	 *
  	 * An endpoint MUST NOT bundle INIT, INIT ACK or
  	 * SHUTDOWN COMPLETE with any other chunks.
  	 */
  	if (!chunk->singleton)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
227
  		return sctp_sf_violation_chunk(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228

ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
229
  	/* Make sure that the SHUTDOWN_COMPLETE chunk has a valid length. */
922dbc5be   Xin Long   sctp: remove the ...
230
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
231
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
232
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
237
238
239
240
241
  
  	/* RFC 2960 10.2 SCTP-to-ULP
  	 *
  	 * H) SHUTDOWN COMPLETE notification
  	 *
  	 * When SCTP completes the shutdown procedures (section 9.2) this
  	 * notification is passed to the upper layer.
  	 */
  	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
a5a35e767   Vlad Yasevich   [SCTP]: Implement...
242
  					     0, 0, 0, NULL, GFP_ATOMIC);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
243
244
  	if (ev)
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
245
  				SCTP_ULPEVENT(ev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  
  	/* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint
  	 * will verify that it is in SHUTDOWN-ACK-SENT state, if it is
  	 * not the chunk should be discarded. If the endpoint is in
  	 * the SHUTDOWN-ACK-SENT state the endpoint should stop the
  	 * T2-shutdown timer and remove all knowledge of the
  	 * association (and thus the association enters the CLOSED
  	 * state).
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_CLOSED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
263
264
  	SCTP_INC_STATS(net, SCTP_MIB_SHUTDOWNS);
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
  
  	return SCTP_DISPOSITION_DELETE_TCB;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  }
  
  /*
   * Respond to a normal INIT chunk.
   * We are the side that is being asked for an association.
   *
   * Section: 5.1 Normal Establishment of an Association, B
   * B) "Z" shall respond immediately with an INIT ACK chunk.  The
   *    destination IP address of the INIT ACK MUST be set to the source
   *    IP address of the INIT to which this INIT ACK is responding.  In
   *    the response, besides filling in other parameters, "Z" must set the
   *    Verification Tag field to Tag_A, and also provide its own
   *    Verification Tag (Tag_Z) in the Initiate Tag field.
   *
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
283
   * Verification Tag: Must be 0.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
287
288
289
290
291
292
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
293
294
295
296
297
298
  enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  {
62e6b7e4e   Xin Long   sctp: remove the ...
300
301
  	struct sctp_chunk *chunk = arg, *repl, *err_chunk;
  	struct sctp_unrecognized_param *unk_param;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  	struct sctp_association *new_asoc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	struct sctp_packet *packet;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  	int len;
2277c7cd7   Richard Haines   sctp: Add LSM hooks
305
306
307
308
  	/* Update socket peer label if first association. */
  	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
  					chunk->skb))
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
  	/* 6.10 Bundling
  	 * An endpoint MUST NOT bundle INIT, INIT ACK or
  	 * SHUTDOWN COMPLETE with any other chunks.
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
312
  	 *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
314
315
316
317
318
  	 * IG Section 2.11.2
  	 * Furthermore, we require that the receiver of an INIT chunk MUST
  	 * enforce these rules by silently discarding an arriving packet
  	 * with an INIT chunk that is bundled with other chunks.
  	 */
  	if (!chunk->singleton)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
319
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
323
  
  	/* If the packet is an OOTB packet which is temporarily on the
  	 * control endpoint, respond with an ABORT.
  	 */
2ce955035   Eric W. Biederman   sctp: Make the ct...
324
  	if (ep == sctp_sk(net->sctp.ctl_sock)->ep) {
b01a24078   Eric W. Biederman   sctp: Make the mi...
325
  		SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
326
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
8190f89df   Wei Yongjun   sctp: Fix the SNM...
327
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
  	/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
330
  	 * Tag.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
  	 */
  	if (chunk->sctp_hdr->vtag != 0)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
333
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
337
338
339
  
  	/* Make sure that the INIT chunk has a valid length.
  	 * Normally, this would cause an ABORT with a Protocol Violation
  	 * error, but since we don't have an association, we'll
  	 * just discard the packet.
  	 */
01a992bea   Xin Long   sctp: remove the ...
340
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
341
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342

bec9640bb   Vlad Yasevich   sctp: Disallow ne...
343
344
345
346
347
348
349
  	/* If the INIT is coming toward a closing socket, we'll send back
  	 * and ABORT.  Essentially, this catches the race of INIT being
  	 * backloged to the socket at the same time as the user isses close().
  	 * Since the socket and all its associations are going away, we
  	 * can treat this OOTB
  	 */
  	if (sctp_sstate(ep->base.sk, CLOSING))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
350
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
bec9640bb   Vlad Yasevich   sctp: Disallow ne...
351

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
  	/* Verify the INIT chunk before processing it. */
  	err_chunk = NULL;
b14878ccb   Vlad Yasevich   net: sctp: cache ...
354
  	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
01a992bea   Xin Long   sctp: remove the ...
355
  			      (struct sctp_init_chunk *)chunk->chunk_hdr, chunk,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
358
359
360
  			      &err_chunk)) {
  		/* This chunk contains fatal error. It is to be discarded.
  		 * Send an ABORT, with causes if there is any.
  		 */
  		if (err_chunk) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
361
  			packet = sctp_abort_pkt_new(net, ep, asoc, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  					(__u8 *)(err_chunk->chunk_hdr) +
922dbc5be   Xin Long   sctp: remove the ...
363
  					sizeof(struct sctp_chunkhdr),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  					ntohs(err_chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
365
  					sizeof(struct sctp_chunkhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
367
368
369
370
371
  
  			sctp_chunk_free(err_chunk);
  
  			if (packet) {
  				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  						SCTP_PACKET(packet));
b01a24078   Eric W. Biederman   sctp: Make the mi...
372
  				SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
  				return SCTP_DISPOSITION_CONSUME;
  			} else {
  				return SCTP_DISPOSITION_NOMEM;
  			}
  		} else {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
378
  			return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
  						    commands);
  		}
  	}
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
382
  	/* Grab the INIT header.  */
4ae70c084   Xin Long   sctp: remove the ...
383
  	chunk->subh.init_hdr = (struct sctp_inithdr *)chunk->skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
  
  	/* Tag the variable length parameters.  */
4ae70c084   Xin Long   sctp: remove the ...
386
  	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(struct sctp_inithdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
389
390
  
  	new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
  	if (!new_asoc)
  		goto nomem;
409b95aff   Vlad Yasevich   sctp: Set source ...
391
392
393
394
  	if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
  					     sctp_scope(sctp_source(chunk)),
  					     GFP_ATOMIC) < 0)
  		goto nomem_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  	/* The call, sctp_process_init(), can fail on memory allocation.  */
de6becdc0   Wei Yongjun   sctp: fix to chec...
396
  	if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
01a992bea   Xin Long   sctp: remove the ...
397
  			       (struct sctp_init_chunk *)chunk->chunk_hdr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  			       GFP_ATOMIC))
  		goto nomem_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
401
402
403
404
405
406
407
  	/* B) "Z" shall respond immediately with an INIT ACK chunk.  */
  
  	/* If there are errors need to be reported for unknown parameters,
  	 * make sure to reserve enough room in the INIT ACK for them.
  	 */
  	len = 0;
  	if (err_chunk)
  		len = ntohs(err_chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
408
  		      sizeof(struct sctp_chunkhdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
  	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
  	if (!repl)
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
412
  		goto nomem_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
414
415
416
417
418
419
420
421
422
423
424
425
  
  	/* If there are errors need to be reported for unknown parameters,
  	 * include them in the outgoing INIT ACK as "Unrecognized parameter"
  	 * parameter.
  	 */
  	if (err_chunk) {
  		/* Get the "Unrecognized parameter" parameter(s) out of the
  		 * ERROR chunk generated by sctp_verify_init(). Since the
  		 * error cause code for "unknown parameter" and the
  		 * "Unrecognized parameter" type is the same, we can
  		 * construct the parameters in INIT ACK by copying the
  		 * ERROR causes over.
  		 */
62e6b7e4e   Xin Long   sctp: remove the ...
426
  		unk_param = (struct sctp_unrecognized_param *)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  			    ((__u8 *)(err_chunk->chunk_hdr) +
922dbc5be   Xin Long   sctp: remove the ...
428
  			    sizeof(struct sctp_chunkhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
430
431
432
433
434
  		/* Replace the cause code with the "Unrecognized parameter"
  		 * parameter type.
  		 */
  		sctp_addto_chunk(repl, len, unk_param);
  		sctp_chunk_free(err_chunk);
  	}
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
435
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
439
440
441
442
443
444
445
446
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  
  	/*
  	 * Note:  After sending out INIT ACK with the State Cookie parameter,
  	 * "Z" MUST NOT allocate any resources, nor keep any states for the
  	 * new association.  Otherwise, "Z" will be vulnerable to resource
  	 * attacks.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
  
  	return SCTP_DISPOSITION_DELETE_TCB;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
  nomem_init:
  	sctp_association_free(new_asoc);
  nomem:
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
450
451
  	if (err_chunk)
  		sctp_chunk_free(err_chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Respond to a normal INIT ACK chunk.
   * We are the side that is initiating the association.
   *
   * Section: 5.1 Normal Establishment of an Association, C
   * C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-init
   *    timer and leave COOKIE-WAIT state. "A" shall then send the State
   *    Cookie received in the INIT ACK chunk in a COOKIE ECHO chunk, start
   *    the T1-cookie timer, and enter the COOKIE-ECHOED state.
   *
   *    Note: The COOKIE ECHO chunk can be bundled with any pending outbound
   *    DATA chunks, but it MUST be the first chunk in the packet and
   *    until the COOKIE ACK is returned the sender MUST NOT send any
   *    other packets to the peer.
   *
   * Verification Tag: 3.3.3
   *   If the value of the Initiate Tag in a received INIT ACK chunk is
   *   found to be 0, the receiver MUST treat it as an error and close the
   *   association by transmitting an ABORT.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
483
484
485
486
487
488
  enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  {
01a992bea   Xin Long   sctp: remove the ...
490
  	struct sctp_init_chunk *initchunk;
172a1599b   Xin Long   sctp: remove the ...
491
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
  	struct sctp_chunk *err_chunk;
  	struct sctp_packet *packet;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
496
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
502
  	/* 6.10 Bundling
  	 * An endpoint MUST NOT bundle INIT, INIT ACK or
  	 * SHUTDOWN COMPLETE with any other chunks.
  	 */
  	if (!chunk->singleton)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
503
  		return sctp_sf_violation_chunk(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
505
  	/* Make sure that the INIT-ACK chunk has a valid length */
cb1844c47   Xin Long   sctp: remove the ...
506
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_initack_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
507
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
508
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  	/* Grab the INIT header.  */
4ae70c084   Xin Long   sctp: remove the ...
510
  	chunk->subh.init_hdr = (struct sctp_inithdr *)chunk->skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
513
  	/* Verify the INIT chunk before processing it. */
  	err_chunk = NULL;
b14878ccb   Vlad Yasevich   net: sctp: cache ...
514
  	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
01a992bea   Xin Long   sctp: remove the ...
515
  			      (struct sctp_init_chunk *)chunk->chunk_hdr, chunk,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  			      &err_chunk)) {
2a4932167   Xin Long   sctp: remove the ...
517
  		enum sctp_error error = SCTP_ERROR_NO_RESOURCE;
853f4b505   Vlad Yasevich   [SCTP]: Correctly...
518

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
  		/* This chunk contains fatal error. It is to be discarded.
d67011913   Vlad Yasevich   [SCTP]: Follow Ad...
520
521
522
  		 * Send an ABORT, with causes.  If there are no causes,
  		 * then there wasn't enough memory.  Just terminate
  		 * the association.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
  		 */
  		if (err_chunk) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
525
  			packet = sctp_abort_pkt_new(net, ep, asoc, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
  					(__u8 *)(err_chunk->chunk_hdr) +
922dbc5be   Xin Long   sctp: remove the ...
527
  					sizeof(struct sctp_chunkhdr),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  					ntohs(err_chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
529
  					sizeof(struct sctp_chunkhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
532
533
534
535
  
  			sctp_chunk_free(err_chunk);
  
  			if (packet) {
  				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  						SCTP_PACKET(packet));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
536
  				SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
537
  				error = SCTP_ERROR_INV_PARAM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  		}
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
540
541
542
543
544
545
546
547
548
  
  		/* SCTP-AUTH, Section 6.3:
  		 *    It should be noted that if the receiver wants to tear
  		 *    down an association in an authenticated way only, the
  		 *    handling of malformed packets should not result in
  		 *    tearing down the association.
  		 *
  		 * This means that if we only want to abort associations
  		 * in an authenticated way (i.e AUTH+ABORT), then we
25985edce   Lucas De Marchi   Fix common misspe...
549
  		 * can't destroy this association just because the packet
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
550
551
552
  		 * was malformed.
  		 */
  		if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
553
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
554

24cb81a6a   Eric W. Biederman   sctp: Push struct...
555
556
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		return sctp_stop_t1_and_abort(net, commands, error, ECONNREFUSED,
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
557
  						asoc, chunk->transport);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
562
  	}
  
  	/* Tag the variable length parameters.  Note that we never
  	 * convert the parameters in an INIT chunk.
  	 */
4ae70c084   Xin Long   sctp: remove the ...
563
  	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(struct sctp_inithdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564

01a992bea   Xin Long   sctp: remove the ...
565
  	initchunk = (struct sctp_init_chunk *)chunk->chunk_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
568
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
  			SCTP_PEER_INIT(initchunk));
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
569
570
  	/* Reset init error count upon receipt of INIT-ACK.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
574
575
576
577
578
579
580
  	/* 5.1 C) "A" shall stop the T1-init timer and leave
  	 * COOKIE-WAIT state.  "A" shall then ... start the T1-cookie
  	 * timer, and enter the COOKIE-ECHOED state.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));
730fc3d05   Vlad Yasevich   [SCTP]: Implete S...
581
582
583
584
  	/* SCTP-AUTH: genereate the assocition shared keys so that
  	 * we can potentially signe the COOKIE-ECHO.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
586
587
588
589
590
591
592
593
594
  	/* 5.1 C) "A" shall then send the State Cookie received in the
  	 * INIT ACK chunk in a COOKIE ECHO chunk, ...
  	 */
  	/* If there is any errors to report, send the ERROR chunk generated
  	 * for unknown parameters as well.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO,
  			SCTP_CHUNK(err_chunk));
  
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  }
59d8d4434   Xin Long   sctp: delay the a...
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk,
  				   const struct sctp_association *asoc)
  {
  	struct sctp_chunk auth;
  
  	if (!chunk->auth_chunk)
  		return true;
  
  	/* SCTP-AUTH:  auth_chunk pointer is only set when the cookie-echo
  	 * is supposed to be authenticated and we have to do delayed
  	 * authentication.  We've just recreated the association using
  	 * the information in the cookie and now it's much easier to
  	 * do the authentication.
  	 */
  
  	/* Make sure that we and the peer are AUTH capable */
  	if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
  		return false;
  
  	/* set-up our fake chunk so that we can process it */
  	auth.skb = chunk->auth_chunk;
  	auth.asoc = chunk->asoc;
  	auth.sctp_hdr = chunk->sctp_hdr;
  	auth.chunk_hdr = (struct sctp_chunkhdr *)
  				skb_push(chunk->auth_chunk,
  					 sizeof(struct sctp_chunkhdr));
  	skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr));
  	auth.transport = chunk->transport;
  
  	return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  /*
   * Respond to a normal COOKIE ECHO chunk.
   * We are the side that is being asked for an association.
   *
   * Section: 5.1 Normal Establishment of an Association, D
   * D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply
   *    with a COOKIE ACK chunk after building a TCB and moving to
   *    the ESTABLISHED state. A COOKIE ACK chunk may be bundled with
   *    any pending DATA chunks (and/or SACK chunks), but the COOKIE ACK
   *    chunk MUST be the first chunk in the packet.
   *
   *   IMPLEMENTATION NOTE: An implementation may choose to send the
   *   Communication Up notification to the SCTP user upon reception
   *   of a valid COOKIE ECHO chunk.
   *
   * Verification Tag: 8.5.1 Exceptions in Verification Tag Rules
   * D) Rules for packet carrying a COOKIE ECHO
   *
   * - When sending a COOKIE ECHO, the endpoint MUST use the value of the
   *   Initial Tag received in the INIT ACK.
   *
   * - The receiver of a COOKIE ECHO follows the procedures in Section 5.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
658
659
660
661
662
663
  enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
  					 const struct sctp_endpoint *ep,
  					 const struct sctp_association *asoc,
  					 const union sctp_subtype type,
  					 void *arg,
  					 struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
  {
30f6ebf65   Xin Long   sctp: add SCTP_AU...
665
  	struct sctp_ulpevent *ev, *ai_ev = NULL, *auth_ev = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
  	struct sctp_association *new_asoc;
01a992bea   Xin Long   sctp: remove the ...
667
  	struct sctp_init_chunk *peer_init;
172a1599b   Xin Long   sctp: remove the ...
668
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
  	struct sctp_chunk *err_chk_p;
172a1599b   Xin Long   sctp: remove the ...
670
  	struct sctp_chunk *repl;
609ee4679   Vlad Yasevich   SCTP: Abort on CO...
671
  	struct sock *sk;
172a1599b   Xin Long   sctp: remove the ...
672
  	int error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
674
675
676
  
  	/* If the packet is an OOTB packet which is temporarily on the
  	 * control endpoint, respond with an ABORT.
  	 */
2ce955035   Eric W. Biederman   sctp: Make the ct...
677
  	if (ep == sctp_sk(net->sctp.ctl_sock)->ep) {
b01a24078   Eric W. Biederman   sctp: Make the mi...
678
  		SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
679
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
8190f89df   Wei Yongjun   sctp: Fix the SNM...
680
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
685
686
  
  	/* Make sure that the COOKIE_ECHO chunk has a valid length.
  	 * In this case, we check that we have enough for at least a
  	 * chunk header.  More detailed verification is done
  	 * in sctp_unpack_cookie().
  	 */
922dbc5be   Xin Long   sctp: remove the ...
687
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
688
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689

609ee4679   Vlad Yasevich   SCTP: Abort on CO...
690
691
692
693
694
695
696
  	/* If the endpoint is not listening or if the number of associations
  	 * on the TCP-style socket exceed the max backlog, respond with an
  	 * ABORT.
  	 */
  	sk = ep->base.sk;
  	if (!sctp_sstate(sk, LISTENING) ||
  	    (sctp_style(sk, TCP) && sk_acceptq_is_full(sk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
697
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
609ee4679   Vlad Yasevich   SCTP: Abort on CO...
698

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
700
701
  	/* "Decode" the chunk.  We have no optional parameters so we
  	 * are in good shape.
  	 */
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
702
  	chunk->subh.cookie_hdr =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
  		(struct sctp_signed_cookie *)chunk->skb->data;
62b08083e   Sridhar Samudrala   [SCTP]: Fix panic...
704
  	if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
705
  					 sizeof(struct sctp_chunkhdr)))
62b08083e   Sridhar Samudrala   [SCTP]: Fix panic...
706
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
  
  	/* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
  	 * "Z" will reply with a COOKIE ACK chunk after building a TCB
  	 * and moving to the ESTABLISHED state.
  	 */
  	new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
  				      &err_chk_p);
  
  	/* FIXME:
  	 * If the re-build failed, what is the proper error path
  	 * from here?
  	 *
  	 * [We should abort the association. --piggy]
  	 */
  	if (!new_asoc) {
  		/* FIXME: Several errors are possible.  A bad cookie should
  		 * be silently discarded, but think about logging it too.
  		 */
  		switch (error) {
  		case -SCTP_IERROR_NOMEM:
  			goto nomem;
  
  		case -SCTP_IERROR_STALE_COOKIE:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
730
  			sctp_send_stale_cookie_err(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
  						   err_chk_p);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
732
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
  
  		case -SCTP_IERROR_BAD_SIG:
  		default:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
736
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
3ff50b799   Stephen Hemminger   [NET]: cleanup ex...
737
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739

df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
740
741
742
  	/* Delay state machine commands until later.
  	 *
  	 * Re-build the bind address for the association is done in
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
745
746
747
748
  	 * the sctp_unpack_cookie() already.
  	 */
  	/* This is a brand-new association, so these are not yet side
  	 * effects--it is safe to run them here.
  	 */
  	peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
de6becdc0   Wei Yongjun   sctp: fix to chec...
749
  	if (!sctp_process_init(new_asoc, chunk,
6a1e5f335   Al Viro   [SCTP]: sctp_proc...
750
  			       &chunk->subh.cookie_hdr->c.peer_addr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
752
  			       peer_init, GFP_ATOMIC))
  		goto nomem_init;
730fc3d05   Vlad Yasevich   [SCTP]: Implete S...
753
754
755
756
757
758
759
  	/* SCTP-AUTH:  Now that we've populate required fields in
  	 * sctp_process_init, set up the assocaition shared keys as
  	 * necessary so that we can potentially authenticate the ACK
  	 */
  	error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC);
  	if (error)
  		goto nomem_init;
59d8d4434   Xin Long   sctp: delay the a...
760
761
762
  	if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) {
  		sctp_association_free(new_asoc);
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
763
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
  	repl = sctp_make_cookie_ack(new_asoc, chunk);
  	if (!repl)
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
766
  		goto nomem_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
769
770
771
772
773
774
775
776
  
  	/* RFC 2960 5.1 Normal Establishment of an Association
  	 *
  	 * D) IMPLEMENTATION NOTE: An implementation may choose to
  	 * send the Communication Up notification to the SCTP user
  	 * upon reception of a valid COOKIE ECHO chunk.
  	 */
  	ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, SCTP_COMM_UP, 0,
  					     new_asoc->c.sinit_num_ostreams,
  					     new_asoc->c.sinit_max_instreams,
a5a35e767   Vlad Yasevich   [SCTP]: Implement...
777
  					     NULL, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
  	if (!ev)
  		goto nomem_ev;
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
780
  	/* Sockets API Draft Section 5.3.1.6
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
781
  	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
  	 * delivers this notification to inform the application that of the
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
783
  	 * peers requested adaptation layer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  	 */
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
785
786
  	if (new_asoc->peer.adaptation_ind) {
  		ai_ev = sctp_ulpevent_make_adaptation_indication(new_asoc,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787
  							    GFP_ATOMIC);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
788
789
790
  		if (!ai_ev)
  			goto nomem_aiev;
  	}
30f6ebf65   Xin Long   sctp: add SCTP_AU...
791
792
793
794
795
796
797
  	if (!new_asoc->peer.auth_capable) {
  		auth_ev = sctp_ulpevent_make_authkey(new_asoc, 0,
  						     SCTP_AUTH_NO_AUTH,
  						     GFP_ATOMIC);
  		if (!auth_ev)
  			goto nomem_authev;
  	}
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
798
799
800
801
802
803
804
805
  	/* Add all the state machine commands now since we've created
  	 * everything.  This way we don't introduce memory corruptions
  	 * during side-effect processing and correclty count established
  	 * associations.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_ESTABLISHED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
806
807
  	SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
  	SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
808
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
9f70f46bd   Neil Horman   sctp: properly la...
809
  	if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
810
811
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
812
813
814
815
816
817
818
819
  	/* This will send the COOKIE ACK */
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  
  	/* Queue the ASSOC_CHANGE event */
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
  
  	/* Send up the Adaptation Layer Indication event */
  	if (ai_ev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
820
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
821
  				SCTP_ULPEVENT(ai_ev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822

30f6ebf65   Xin Long   sctp: add SCTP_AU...
823
824
825
  	if (auth_ev)
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(auth_ev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
  	return SCTP_DISPOSITION_CONSUME;
30f6ebf65   Xin Long   sctp: add SCTP_AU...
827
828
  nomem_authev:
  	sctp_ulpevent_free(ai_ev);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
829
830
  nomem_aiev:
  	sctp_ulpevent_free(ev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
832
  nomem_ev:
  	sctp_chunk_free(repl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
834
835
836
837
838
839
840
  nomem_init:
  	sctp_association_free(new_asoc);
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Respond to a normal COOKIE ACK chunk.
b52effd26   Marcelo Ricardo Leitner   sctp: fix cut and...
841
   * We are the side that is asking for an association.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
   *
   * RFC 2960 5.1 Normal Establishment of an Association
   *
   * E) Upon reception of the COOKIE ACK, endpoint "A" will move from the
   *    COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-cookie
   *    timer. It may also notify its ULP about the successful
   *    establishment of the association with a Communication Up
   *    notification (see Section 10).
   *
   * Verification Tag:
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
860
861
862
863
864
865
  enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
  					 const struct sctp_endpoint *ep,
  					 const struct sctp_association *asoc,
  					 const union sctp_subtype type,
  					 void *arg,
  					 struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
867
868
869
870
  {
  	struct sctp_chunk *chunk = arg;
  	struct sctp_ulpevent *ev;
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
871
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
  
  	/* Verify that the chunk length for the COOKIE-ACK is OK.
  	 * If we don't do this, any bundled chunks may be junked.
  	 */
922dbc5be   Xin Long   sctp: remove the ...
876
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
877
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
879
880
881
882
883
884
885
  						  commands);
  
  	/* Reset init error count upon receipt of COOKIE-ACK,
  	 * to avoid problems with the managemement of this
  	 * counter in stale cookie situations when a transition back
  	 * from the COOKIE-ECHOED state to the COOKIE-WAIT
  	 * state is performed.
  	 */
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
886
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887

2277c7cd7   Richard Haines   sctp: Add LSM hooks
888
889
  	/* Set peer label for connection. */
  	security_inet_conn_established(ep->base.sk, chunk->skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
891
892
893
894
895
896
897
898
899
  	/* RFC 2960 5.1 Normal Establishment of an Association
  	 *
  	 * E) Upon reception of the COOKIE ACK, endpoint "A" will move
  	 * from the COOKIE-ECHOED state to the ESTABLISHED state,
  	 * stopping the T1-cookie timer.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_ESTABLISHED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
900
901
  	SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
  	SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
9f70f46bd   Neil Horman   sctp: properly la...
903
  	if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
905
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
908
909
910
911
912
913
  
  	/* It may also notify its ULP about the successful
  	 * establishment of the association with a Communication Up
  	 * notification (see Section 10).
  	 */
  	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP,
  					     0, asoc->c.sinit_num_ostreams,
  					     asoc->c.sinit_max_instreams,
a5a35e767   Vlad Yasevich   [SCTP]: Implement...
914
  					     NULL, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
916
917
918
919
920
921
  
  	if (!ev)
  		goto nomem;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
  
  	/* Sockets API Draft Section 5.3.1.6
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
922
  	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923
  	 * delivers this notification to inform the application that of the
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
924
  	 * peers requested adaptation layer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
  	 */
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
926
927
  	if (asoc->peer.adaptation_ind) {
  		ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
929
930
931
932
933
  		if (!ev)
  			goto nomem;
  
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(ev));
  	}
30f6ebf65   Xin Long   sctp: add SCTP_AU...
934
935
936
937
938
939
940
941
  	if (!asoc->peer.auth_capable) {
  		ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH,
  						GFP_ATOMIC);
  		if (!ev)
  			goto nomem;
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(ev));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
943
944
945
946
947
  	return SCTP_DISPOSITION_CONSUME;
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /* Generate and sendout a heartbeat packet.  */
172a1599b   Xin Long   sctp: remove the ...
948
949
950
951
952
953
  static enum sctp_disposition sctp_sf_heartbeat(
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
955
956
  {
  	struct sctp_transport *transport = (struct sctp_transport *) arg;
  	struct sctp_chunk *reply;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
957
958
  
  	/* Send a heartbeat to our peer.  */
92c73af58   Wei Yongjun   sctp: make heartb...
959
  	reply = sctp_make_heartbeat(asoc, transport);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
961
962
963
964
965
966
967
968
969
970
971
972
973
  	if (!reply)
  		return SCTP_DISPOSITION_NOMEM;
  
  	/* Set rto_pending indicating that an RTT measurement
  	 * is started with this heartbeat chunk.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_RTO_PENDING,
  			SCTP_TRANSPORT(transport));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /* Generate a HEARTBEAT packet on the given transport.  */
172a1599b   Xin Long   sctp: remove the ...
974
975
976
977
978
979
  enum sctp_disposition sctp_sf_sendbeat_8_3(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
981
  {
  	struct sctp_transport *transport = (struct sctp_transport *) arg;
b9f847868   Vlad Yasevich   sctp: Fix error c...
982
  	if (asoc->overall_error_count >= asoc->max_retrans) {
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
983
984
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
986
  		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
987
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
b01a24078   Eric W. Biederman   sctp: Make the mi...
988
989
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
992
993
994
995
996
997
998
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
  
  	/* Section 3.3.5.
  	 * The Sender-specific Heartbeat Info field should normally include
  	 * information about the sender's current time when this HEARTBEAT
  	 * chunk is sent and the destination transport address to which this
  	 * HEARTBEAT is sent (see Section 8.3).
  	 */
52ccb8e90   Frank Filz   [SCTP]: Update SC...
999
  	if (transport->param_flags & SPP_HB_ENABLE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000
1001
1002
1003
  		if (SCTP_DISPOSITION_NOMEM ==
  				sctp_sf_heartbeat(ep, asoc, type, arg,
  						  commands))
  			return SCTP_DISPOSITION_NOMEM;
245cba7e5   Vlad Yasevich   sctp: Remove usel...
1004

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
1006
1007
  		/* Set transport error counter and association error counter
  		 * when sending heartbeat.
  		 */
7e99013a5   Vlad Yasevich   sctp: Fix broken ...
1008
  		sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
1010
  				SCTP_TRANSPORT(transport));
  	}
245cba7e5   Vlad Yasevich   sctp: Remove usel...
1011
1012
  	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE,
  			SCTP_TRANSPORT(transport));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1013
1014
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
  			SCTP_TRANSPORT(transport));
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
1015
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  }
7b9438de0   Xin Long   sctp: add stream ...
1017
  /* resend asoc strreset_chunk.  */
172a1599b   Xin Long   sctp: remove the ...
1018
1019
1020
1021
1022
1023
  enum sctp_disposition sctp_sf_send_reconf(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
7b9438de0   Xin Long   sctp: add stream ...
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
  {
  	struct sctp_transport *transport = arg;
  
  	if (asoc->overall_error_count >= asoc->max_retrans) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
  		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
  
  	sctp_chunk_hold(asoc->strreset_chunk);
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  			SCTP_CHUNK(asoc->strreset_chunk));
  	sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
  /*
   * Process an heartbeat request.
   *
   * Section: 8.3 Path Heartbeat
   * The receiver of the HEARTBEAT should immediately respond with a
   * HEARTBEAT ACK that contains the Heartbeat Information field copied
   * from the received HEARTBEAT chunk.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   * When receiving an SCTP packet, the endpoint MUST ensure that the
   * value in the Verification Tag field of the received SCTP packet
   * matches its own Tag. If the received Verification Tag value does not
   * match the receiver's own tag value, the receiver shall silently
   * discard the packet and shall not process it any further except for
   * those cases listed in Section 8.5.1 below.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
1069
1070
1071
1072
1073
  enum sctp_disposition sctp_sf_beat_8_3(struct net *net,
  				       const struct sctp_endpoint *ep,
  				       const struct sctp_association *asoc,
  				       const union sctp_subtype type,
  				       void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
  {
3c9187049   Xin Long   sctp: remove the ...
1075
  	struct sctp_paramhdr *param_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1076
1077
1078
1079
1080
  	struct sctp_chunk *chunk = arg;
  	struct sctp_chunk *reply;
  	size_t paylen = 0;
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1081
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1082
1083
  
  	/* Make sure that the HEARTBEAT chunk has a valid length. */
38c00f748   Xin Long   sctp: remove the ...
1084
1085
  	if (!sctp_chunk_length_valid(chunk,
  				     sizeof(struct sctp_heartbeat_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1086
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1087
1088
1089
1090
1091
1092
  						  commands);
  
  	/* 8.3 The receiver of the HEARTBEAT should immediately
  	 * respond with a HEARTBEAT ACK that contains the Heartbeat
  	 * Information field copied from the received HEARTBEAT chunk.
  	 */
4d2dcdf4e   Xin Long   sctp: remove the ...
1093
  	chunk->subh.hb_hdr = (struct sctp_heartbeathdr *)chunk->skb->data;
3c9187049   Xin Long   sctp: remove the ...
1094
  	param_hdr = (struct sctp_paramhdr *)chunk->subh.hb_hdr;
922dbc5be   Xin Long   sctp: remove the ...
1095
  	paylen = ntohs(chunk->chunk_hdr->length) - sizeof(struct sctp_chunkhdr);
06a31e2b9   Thomas Graf   sctp: verify leng...
1096
1097
1098
1099
  
  	if (ntohs(param_hdr->length) > paylen)
  		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
  						  param_hdr, commands);
62b08083e   Sridhar Samudrala   [SCTP]: Fix panic...
1100
1101
  	if (!pskb_pull(chunk->skb, paylen))
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1102

06a31e2b9   Thomas Graf   sctp: verify leng...
1103
  	reply = sctp_make_heartbeat_ack(asoc, chunk, param_hdr, paylen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
  	if (!reply)
  		goto nomem;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Process the returning HEARTBEAT ACK.
   *
   * Section: 8.3 Path Heartbeat
   * Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT
   * should clear the error counter of the destination transport
   * address to which the HEARTBEAT was sent, and mark the destination
   * transport address as active if it is not so marked. The endpoint may
   * optionally report to the upper layer when an inactive destination
   * address is marked as active due to the reception of the latest
   * HEARTBEAT ACK. The receiver of the HEARTBEAT ACK must also
   * clear the association overall error count as well (as defined
   * in section 8.1).
   *
   * The receiver of the HEARTBEAT ACK should also perform an RTT
   * measurement for that destination transport address using the time
   * value carried in the HEARTBEAT ACK chunk.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
1142
1143
1144
1145
1146
1147
  enum sctp_disposition sctp_sf_backbeat_8_3(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
  {
edf903f83   Xin Long   sctp: remove the ...
1149
  	struct sctp_sender_hb_info *hbinfo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1150
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
  	struct sctp_transport *link;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
  	unsigned long max_interval;
edf903f83   Xin Long   sctp: remove the ...
1153
  	union sctp_addr from_addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1154
1155
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1156
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
1158
  
  	/* Make sure that the HEARTBEAT-ACK chunk has a valid length.  */
922dbc5be   Xin Long   sctp: remove the ...
1159
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr) +
edf903f83   Xin Long   sctp: remove the ...
1160
  					    sizeof(*hbinfo)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1161
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
  						  commands);
edf903f83   Xin Long   sctp: remove the ...
1163
  	hbinfo = (struct sctp_sender_hb_info *)chunk->skb->data;
a601266e4   Vladislav Yasevich   [SCTP]: Validate ...
1164
  	/* Make sure that the length of the parameter is what we expect */
edf903f83   Xin Long   sctp: remove the ...
1165
  	if (ntohs(hbinfo->param_hdr.length) != sizeof(*hbinfo))
a601266e4   Vladislav Yasevich   [SCTP]: Validate ...
1166
  		return SCTP_DISPOSITION_DISCARD;
a601266e4   Vladislav Yasevich   [SCTP]: Validate ...
1167

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1168
  	from_addr = hbinfo->daddr;
63de08f45   Al Viro   [SCTP]: Switch ad...
1169
  	link = sctp_assoc_lookup_paddr(asoc, &from_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1170
1171
  
  	/* This should never happen, but lets log it if so.  */
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
1172
1173
  	if (unlikely(!link)) {
  		if (from_addr.sa.sa_family == AF_INET6) {
e87cc4728   Joe Perches   net: Convert net_...
1174
1175
1176
1177
1178
  			net_warn_ratelimited("%s association %p could not find address %pI6
  ",
  					     __func__,
  					     asoc,
  					     &from_addr.v6.sin6_addr);
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
1179
  		} else {
e87cc4728   Joe Perches   net: Convert net_...
1180
1181
1182
1183
1184
  			net_warn_ratelimited("%s association %p could not find address %pI4
  ",
  					     __func__,
  					     asoc,
  					     &from_addr.v4.sin_addr.s_addr);
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
1185
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
1187
  		return SCTP_DISPOSITION_DISCARD;
  	}
ad8fec172   Sridhar Samudrala   [SCTP]: Verify al...
1188
1189
1190
  	/* Validate the 64-bit random nonce. */
  	if (hbinfo->hb_nonce != link->hb_nonce)
  		return SCTP_DISPOSITION_DISCARD;
52ccb8e90   Frank Filz   [SCTP]: Update SC...
1191
  	max_interval = link->hbinterval + link->rto;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192
1193
1194
1195
  
  	/* Check if the timestamp looks valid.  */
  	if (time_after(hbinfo->sent_at, jiffies) ||
  	    time_after(jiffies, hbinfo->sent_at + max_interval)) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
1196
1197
1198
  		pr_debug("%s: HEARTBEAT ACK with invalid timestamp received "
  			 "for transport:%p
  ", __func__, link);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  		return SCTP_DISPOSITION_DISCARD;
  	}
  
  	/* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of
  	 * the HEARTBEAT should clear the error counter of the
  	 * destination transport address to which the HEARTBEAT was
  	 * sent and mark the destination transport address as active if
  	 * it is not so marked.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, SCTP_TRANSPORT(link));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /* Helper function to send out an abort for the restart
   * condition.
   */
2ce955035   Eric W. Biederman   sctp: Make the ct...
1216
  static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217
  				      struct sctp_chunk *init,
a85bbeb22   Xin Long   sctp: remove the ...
1218
  				      struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1219
  {
172a1599b   Xin Long   sctp: remove the ...
1220
  	struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
1222
  	union sctp_addr_param *addrparm;
  	struct sctp_errhdr *errhdr;
d8238d9da   Xin Long   sctp: remove the ...
1223
  	char buffer[sizeof(*errhdr) + sizeof(*addrparm)];
172a1599b   Xin Long   sctp: remove the ...
1224
1225
1226
  	struct sctp_endpoint *ep;
  	struct sctp_packet *pkt;
  	int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1227
1228
1229
1230
1231
1232
1233
1234
1235
  
  	/* Build the error on the stack.   We are way to malloc crazy
  	 * throughout the code today.
  	 */
  	errhdr = (struct sctp_errhdr *)buffer;
  	addrparm = (union sctp_addr_param *)errhdr->variable;
  
  	/* Copy into a parm format. */
  	len = af->to_addr_param(ssa, addrparm);
d8238d9da   Xin Long   sctp: remove the ...
1236
  	len += sizeof(*errhdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
1238
1239
1240
1241
  
  	errhdr->cause = SCTP_ERROR_RESTART;
  	errhdr->length = htons(len);
  
  	/* Assign to the control socket. */
2ce955035   Eric W. Biederman   sctp: Make the ct...
1242
  	ep = sctp_sk(net->sctp.ctl_sock)->ep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243
1244
1245
1246
  
  	/* Association is NULL since this may be a restart attack and we
  	 * want to send back the attacker's vtag.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1247
  	pkt = sctp_abort_pkt_new(net, ep, NULL, init, errhdr, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1248
1249
1250
1251
  
  	if (!pkt)
  		goto out;
  	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(pkt));
b01a24078   Eric W. Biederman   sctp: Make the mi...
1252
  	SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
  
  	/* Discard the rest of the inbound packet. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
  
  out:
  	/* Even if there is no memory, treat as a failure so
  	 * the packet will get dropped.
  	 */
  	return 0;
  }
123031c0e   Joe Perches   sctp: fix test fo...
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
  static bool list_has_sctp_addr(const struct list_head *list,
  			       union sctp_addr *ipaddr)
  {
  	struct sctp_transport *addr;
  
  	list_for_each_entry(addr, list, transports) {
  		if (sctp_cmp_addr_exact(ipaddr, &addr->ipaddr))
  			return true;
  	}
  
  	return false;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
1276
1277
1278
1279
1280
  /* A restart is occurring, check to make sure no new addresses
   * are being added as we may be under a takeover attack.
   */
  static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
  				       const struct sctp_association *asoc,
  				       struct sctp_chunk *init,
a85bbeb22   Xin Long   sctp: remove the ...
1281
  				       struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1282
  {
4e7696d90   Xin Long   sctp: get netns f...
1283
  	struct net *net = new_asoc->base.net;
123031c0e   Joe Perches   sctp: fix test fo...
1284
1285
  	struct sctp_transport *new_addr;
  	int ret = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286

123031c0e   Joe Perches   sctp: fix test fo...
1287
  	/* Implementor's Guide - Section 5.2.2
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
  	 * ...
  	 * Before responding the endpoint MUST check to see if the
  	 * unexpected INIT adds new addresses to the association. If new
  	 * addresses are added to the association, the endpoint MUST respond
  	 * with an ABORT..
  	 */
  
  	/* Search through all current addresses and make sure
  	 * we aren't adding any new ones.
  	 */
9dbc15f05   Robert P. J. Day   [SCTP]: "list_for...
1298
  	list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list,
123031c0e   Joe Perches   sctp: fix test fo...
1299
1300
1301
  			    transports) {
  		if (!list_has_sctp_addr(&asoc->peer.transport_addr_list,
  					&new_addr->ipaddr)) {
2ce955035   Eric W. Biederman   sctp: Make the ct...
1302
  			sctp_sf_send_restart_abort(net, &new_addr->ipaddr, init,
123031c0e   Joe Perches   sctp: fix test fo...
1303
1304
  						   commands);
  			ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
  			break;
123031c0e   Joe Perches   sctp: fix test fo...
1306
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307
1308
1309
  	}
  
  	/* Return success if all addresses were found. */
123031c0e   Joe Perches   sctp: fix test fo...
1310
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  }
  
  /* Populate the verification/tie tags based on overlapping INIT
   * scenario.
   *
   * Note: Do not use in CLOSED or SHUTDOWN-ACK-SENT state.
   */
  static void sctp_tietags_populate(struct sctp_association *new_asoc,
  				  const struct sctp_association *asoc)
  {
  	switch (asoc->state) {
  
  	/* 5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State */
  
  	case SCTP_STATE_COOKIE_WAIT:
  		new_asoc->c.my_vtag     = asoc->c.my_vtag;
  		new_asoc->c.my_ttag     = asoc->c.my_vtag;
  		new_asoc->c.peer_ttag   = 0;
  		break;
  
  	case SCTP_STATE_COOKIE_ECHOED:
  		new_asoc->c.my_vtag     = asoc->c.my_vtag;
  		new_asoc->c.my_ttag     = asoc->c.my_vtag;
  		new_asoc->c.peer_ttag   = asoc->c.peer_vtag;
  		break;
  
  	/* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
  	 * COOKIE-WAIT and SHUTDOWN-ACK-SENT
  	 */
  	default:
  		new_asoc->c.my_ttag   = asoc->c.my_vtag;
  		new_asoc->c.peer_ttag = asoc->c.peer_vtag;
  		break;
3ff50b799   Stephen Hemminger   [NET]: cleanup ex...
1344
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  
  	/* Other parameters for the endpoint SHOULD be copied from the
  	 * existing parameters of the association (e.g. number of
  	 * outbound streams) into the INIT ACK and cookie.
  	 */
  	new_asoc->rwnd                  = asoc->rwnd;
  	new_asoc->c.sinit_num_ostreams  = asoc->c.sinit_num_ostreams;
  	new_asoc->c.sinit_max_instreams = asoc->c.sinit_max_instreams;
  	new_asoc->c.initial_tsn         = asoc->c.initial_tsn;
  }
  
  /*
   * Compare vtag/tietag values to determine unexpected COOKIE-ECHO
   * handling action.
   *
   * RFC 2960 5.2.4 Handle a COOKIE ECHO when a TCB exists.
   *
   * Returns value representing action to be taken.   These action values
   * correspond to Action/Description values in RFC 2960, Table 2.
   */
  static char sctp_tietags_compare(struct sctp_association *new_asoc,
  				 const struct sctp_association *asoc)
  {
  	/* In this case, the peer may have restarted.  */
  	if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
  	    (asoc->c.peer_vtag != new_asoc->c.peer_vtag) &&
  	    (asoc->c.my_vtag == new_asoc->c.my_ttag) &&
  	    (asoc->c.peer_vtag == new_asoc->c.peer_ttag))
  		return 'A';
  
  	/* Collision case B. */
  	if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
  	    ((asoc->c.peer_vtag != new_asoc->c.peer_vtag) ||
  	     (0 == asoc->c.peer_vtag))) {
  		return 'B';
  	}
  
  	/* Collision case D. */
  	if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
  	    (asoc->c.peer_vtag == new_asoc->c.peer_vtag))
  		return 'D';
  
  	/* Collision case C. */
  	if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
  	    (asoc->c.peer_vtag == new_asoc->c.peer_vtag) &&
  	    (0 == new_asoc->c.my_ttag) &&
  	    (0 == new_asoc->c.peer_ttag))
  		return 'C';
  
  	/* No match to any of the special cases; discard this packet. */
  	return 'E';
  }
  
  /* Common helper routine for both duplicate and simulataneous INIT
   * chunk handling.
   */
172a1599b   Xin Long   sctp: remove the ...
1401
1402
1403
1404
1405
1406
1407
  static enum sctp_disposition sctp_sf_do_unexpected_init(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
  {
62e6b7e4e   Xin Long   sctp: remove the ...
1409
1410
  	struct sctp_chunk *chunk = arg, *repl, *err_chunk;
  	struct sctp_unrecognized_param *unk_param;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1411
  	struct sctp_association *new_asoc;
172a1599b   Xin Long   sctp: remove the ...
1412
  	enum sctp_disposition retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
  	struct sctp_packet *packet;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
  	int len;
2277c7cd7   Richard Haines   sctp: Add LSM hooks
1415
1416
1417
1418
  	/* Update socket peer label if first association. */
  	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
  					chunk->skb))
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
  	/* 6.10 Bundling
  	 * An endpoint MUST NOT bundle INIT, INIT ACK or
  	 * SHUTDOWN COMPLETE with any other chunks.
  	 *
  	 * IG Section 2.11.2
  	 * Furthermore, we require that the receiver of an INIT chunk MUST
  	 * enforce these rules by silently discarding an arriving packet
  	 * with an INIT chunk that is bundled with other chunks.
  	 */
  	if (!chunk->singleton)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1429
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
1431
  
  	/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
1432
  	 * Tag.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1433
1434
  	 */
  	if (chunk->sctp_hdr->vtag != 0)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1435
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1436
1437
1438
1439
1440
  
  	/* Make sure that the INIT chunk has a valid length.
  	 * In this case, we generate a protocol violation since we have
  	 * an association established.
  	 */
01a992bea   Xin Long   sctp: remove the ...
1441
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1442
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443
1444
  						  commands);
  	/* Grab the INIT header.  */
4ae70c084   Xin Long   sctp: remove the ...
1445
  	chunk->subh.init_hdr = (struct sctp_inithdr *)chunk->skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1446
1447
  
  	/* Tag the variable length parameters.  */
4ae70c084   Xin Long   sctp: remove the ...
1448
  	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(struct sctp_inithdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1449
1450
1451
  
  	/* Verify the INIT chunk before processing it. */
  	err_chunk = NULL;
b14878ccb   Vlad Yasevich   net: sctp: cache ...
1452
  	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
01a992bea   Xin Long   sctp: remove the ...
1453
  			      (struct sctp_init_chunk *)chunk->chunk_hdr, chunk,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1454
1455
1456
1457
1458
  			      &err_chunk)) {
  		/* This chunk contains fatal error. It is to be discarded.
  		 * Send an ABORT, with causes if there is any.
  		 */
  		if (err_chunk) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1459
  			packet = sctp_abort_pkt_new(net, ep, asoc, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
  					(__u8 *)(err_chunk->chunk_hdr) +
922dbc5be   Xin Long   sctp: remove the ...
1461
  					sizeof(struct sctp_chunkhdr),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1462
  					ntohs(err_chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
1463
  					sizeof(struct sctp_chunkhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
1466
1467
  
  			if (packet) {
  				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  						SCTP_PACKET(packet));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1468
  				SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1469
1470
1471
1472
1473
1474
  				retval = SCTP_DISPOSITION_CONSUME;
  			} else {
  				retval = SCTP_DISPOSITION_NOMEM;
  			}
  			goto cleanup;
  		} else {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1475
  			return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
  						    commands);
  		}
  	}
  
  	/*
  	 * Other parameters for the endpoint SHOULD be copied from the
  	 * existing parameters of the association (e.g. number of
  	 * outbound streams) into the INIT ACK and cookie.
  	 * FIXME:  We are copying parameters from the endpoint not the
  	 * association.
  	 */
  	new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
  	if (!new_asoc)
  		goto nomem;
409b95aff   Vlad Yasevich   sctp: Set source ...
1490
1491
1492
  	if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
  				sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1493
1494
1495
1496
  	/* In the outbound INIT ACK the endpoint MUST copy its current
  	 * Verification Tag and Peers Verification tag into a reserved
  	 * place (local tie-tag and per tie-tag) within the state cookie.
  	 */
de6becdc0   Wei Yongjun   sctp: fix to chec...
1497
  	if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
01a992bea   Xin Long   sctp: remove the ...
1498
  			       (struct sctp_init_chunk *)chunk->chunk_hdr,
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1499
1500
  			       GFP_ATOMIC))
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
  
  	/* Make sure no new addresses are being added during the
  	 * restart.   Do not do this check for COOKIE-WAIT state,
  	 * since there are no peer addresses to check against.
  	 * Upon return an ABORT will have been sent if needed.
  	 */
  	if (!sctp_state(asoc, COOKIE_WAIT)) {
  		if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk,
  						 commands)) {
  			retval = SCTP_DISPOSITION_CONSUME;
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1511
  			goto nomem_retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
  		}
  	}
  
  	sctp_tietags_populate(new_asoc, asoc);
  
  	/* B) "Z" shall respond immediately with an INIT ACK chunk.  */
  
  	/* If there are errors need to be reported for unknown parameters,
  	 * make sure to reserve enough room in the INIT ACK for them.
  	 */
  	len = 0;
  	if (err_chunk) {
  		len = ntohs(err_chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
1525
  		      sizeof(struct sctp_chunkhdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1526
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
  	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
  	if (!repl)
  		goto nomem;
  
  	/* If there are errors need to be reported for unknown parameters,
  	 * include them in the outgoing INIT ACK as "Unrecognized parameter"
  	 * parameter.
  	 */
  	if (err_chunk) {
  		/* Get the "Unrecognized parameter" parameter(s) out of the
  		 * ERROR chunk generated by sctp_verify_init(). Since the
  		 * error cause code for "unknown parameter" and the
  		 * "Unrecognized parameter" type is the same, we can
  		 * construct the parameters in INIT ACK by copying the
  		 * ERROR causes over.
  		 */
62e6b7e4e   Xin Long   sctp: remove the ...
1543
  		unk_param = (struct sctp_unrecognized_param *)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
  			    ((__u8 *)(err_chunk->chunk_hdr) +
922dbc5be   Xin Long   sctp: remove the ...
1545
  			    sizeof(struct sctp_chunkhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
  		/* Replace the cause code with the "Unrecognized parameter"
  		 * parameter type.
  		 */
  		sctp_addto_chunk(repl, len, unk_param);
  	}
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  
  	/*
  	 * Note: After sending out INIT ACK with the State Cookie parameter,
  	 * "Z" MUST NOT allocate any resources for this new association.
  	 * Otherwise, "Z" will be vulnerable to resource attacks.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
  	retval = SCTP_DISPOSITION_CONSUME;
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1562
1563
1564
1565
1566
1567
1568
  	return retval;
  
  nomem:
  	retval = SCTP_DISPOSITION_NOMEM;
  nomem_retval:
  	if (new_asoc)
  		sctp_association_free(new_asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
1571
1572
  cleanup:
  	if (err_chunk)
  		sctp_chunk_free(err_chunk);
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573
1574
1575
  }
  
  /*
25985edce   Lucas De Marchi   Fix common misspe...
1576
   * Handle simultaneous INIT.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
   * This means we started an INIT and then we got an INIT request from
   * our peer.
   *
   * Section: 5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)
   * This usually indicates an initialization collision, i.e., each
   * endpoint is attempting, at about the same time, to establish an
   * association with the other endpoint.
   *
   * Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
   * endpoint MUST respond with an INIT ACK using the same parameters it
   * sent in its original INIT chunk (including its Verification Tag,
   * unchanged). These original parameters are combined with those from the
   * newly received INIT chunk. The endpoint shall also generate a State
   * Cookie with the INIT ACK. The endpoint uses the parameters sent in its
   * INIT to calculate the State Cookie.
   *
   * After that, the endpoint MUST NOT change its state, the T1-init
   * timer shall be left running and the corresponding TCB MUST NOT be
   * destroyed. The normal procedures for handling State Cookies when
   * a TCB exists will resolve the duplicate INITs to a single association.
   *
   * For an endpoint that is in the COOKIE-ECHOED state it MUST populate
   * its Tie-Tags with the Tag information of itself and its peer (see
   * section 5.2.2 for a description of the Tie-Tags).
   *
   * Verification Tag: Not explicit, but an INIT can not have a valid
   * verification tag, so we skip the check.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
1613
1614
1615
1616
1617
1618
1619
  enum sctp_disposition sctp_sf_do_5_2_1_siminit(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620
1621
1622
1623
  {
  	/* Call helper to do the real work for both simulataneous and
  	 * duplicate INIT chunk handling.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1624
  	return sctp_sf_do_unexpected_init(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
  }
  
  /*
   * Handle duplicated INIT messages.  These are usually delayed
   * restransmissions.
   *
   * Section: 5.2.2 Unexpected INIT in States Other than CLOSED,
   * COOKIE-ECHOED and COOKIE-WAIT
   *
   * Unless otherwise stated, upon reception of an unexpected INIT for
   * this association, the endpoint shall generate an INIT ACK with a
   * State Cookie.  In the outbound INIT ACK the endpoint MUST copy its
   * current Verification Tag and peer's Verification Tag into a reserved
   * place within the state cookie.  We shall refer to these locations as
   * the Peer's-Tie-Tag and the Local-Tie-Tag.  The outbound SCTP packet
   * containing this INIT ACK MUST carry a Verification Tag value equal to
   * the Initiation Tag found in the unexpected INIT.  And the INIT ACK
   * MUST contain a new Initiation Tag (randomly generated see Section
   * 5.3.1).  Other parameters for the endpoint SHOULD be copied from the
   * existing parameters of the association (e.g. number of outbound
   * streams) into the INIT ACK and cookie.
   *
   * After sending out the INIT ACK, the endpoint shall take no further
   * actions, i.e., the existing association, including its current state,
   * and the corresponding TCB MUST NOT be changed.
   *
   * Note: Only when a TCB exists and the association is not in a COOKIE-
   * WAIT state are the Tie-Tags populated.  For a normal association INIT
   * (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be
   * set to 0 (indicating that no previous TCB existed).  The INIT ACK and
   * State Cookie are populated as specified in section 5.2.1.
   *
   * Verification Tag: Not specified, but an INIT has no way of knowing
   * what the verification tag could be, so we ignore it.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
1668
1669
  enum sctp_disposition sctp_sf_do_5_2_2_dupinit(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1670
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1671
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
1672
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
1674
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1675
1676
1677
1678
  {
  	/* Call helper to do the real work for both simulataneous and
  	 * duplicate INIT chunk handling.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1679
  	return sctp_sf_do_unexpected_init(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
  }
610ab73ac   Vlad Yasevich   [SCTP]: Correctly...
1681
1682
1683
1684
1685
1686
1687
1688
1689
  /*
   * Unexpected INIT-ACK handler.
   *
   * Section 5.2.3
   * If an INIT ACK received by an endpoint in any state other than the
   * COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk.
   * An unexpected INIT ACK usually indicates the processing of an old or
   * duplicated INIT chunk.
  */
172a1599b   Xin Long   sctp: remove the ...
1690
1691
1692
1693
1694
1695
1696
  enum sctp_disposition sctp_sf_do_5_2_3_initack(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
610ab73ac   Vlad Yasevich   [SCTP]: Correctly...
1697
1698
1699
1700
  {
  	/* Per the above section, we'll discard the chunk if we have an
  	 * endpoint.  If this is an OOTB INIT-ACK, treat it as such.
  	 */
2ce955035   Eric W. Biederman   sctp: Make the ct...
1701
  	if (ep == sctp_sk(net->sctp.ctl_sock)->ep)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1702
  		return sctp_sf_ootb(net, ep, asoc, type, arg, commands);
610ab73ac   Vlad Yasevich   [SCTP]: Correctly...
1703
  	else
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1704
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
610ab73ac   Vlad Yasevich   [SCTP]: Correctly...
1705
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
1707
1708
1709
1710
1711
  
  /* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
   *
   * Section 5.2.4
   *  A)  In this case, the peer may have restarted.
   */
172a1599b   Xin Long   sctp: remove the ...
1712
1713
  static enum sctp_disposition sctp_sf_do_dupcook_a(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1714
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715
1716
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
1717
  					struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718
1719
  					struct sctp_association *new_asoc)
  {
01a992bea   Xin Long   sctp: remove the ...
1720
  	struct sctp_init_chunk *peer_init;
172a1599b   Xin Long   sctp: remove the ...
1721
  	enum sctp_disposition disposition;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
1723
1724
  	struct sctp_ulpevent *ev;
  	struct sctp_chunk *repl;
  	struct sctp_chunk *err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1725
1726
1727
1728
1729
  
  	/* new_asoc is a brand-new association, so these are not yet
  	 * side effects--it is safe to run them here.
  	 */
  	peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
de6becdc0   Wei Yongjun   sctp: fix to chec...
1730
  	if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
1732
  			       GFP_ATOMIC))
  		goto nomem;
4842a08fb   Xin Long   sctp: init active...
1733
1734
  	if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC))
  		goto nomem;
59d8d4434   Xin Long   sctp: delay the a...
1735
1736
  	if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
  		return SCTP_DISPOSITION_DISCARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
1738
1739
1740
  	/* Make sure no new addresses are being added during the
  	 * restart.  Though this is a pretty complicated attack
  	 * since you'd have to get inside the cookie.
  	 */
59d8d4434   Xin Long   sctp: delay the a...
1741
  	if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1742
  		return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1743
1744
1745
1746
1747
1748
1749
1750
  
  	/* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
  	 * the peer has restarted (Action A), it MUST NOT setup a new
  	 * association but instead resend the SHUTDOWN ACK and send an ERROR
  	 * chunk with a "Cookie Received while Shutting Down" error cause to
  	 * its peer.
  	*/
  	if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1751
  		disposition = sctp_sf_do_9_2_reshutack(net, ep, asoc,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1752
1753
1754
1755
1756
1757
1758
  				SCTP_ST_CHUNK(chunk->chunk_hdr->type),
  				chunk, commands);
  		if (SCTP_DISPOSITION_NOMEM == disposition)
  			goto nomem;
  
  		err = sctp_make_op_error(asoc, chunk,
  					 SCTP_ERROR_COOKIE_IN_SHUTDOWN,
6383cfb3e   Vlad Yasevich   sctp: Fix malform...
1759
  					 NULL, 0, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1760
1761
1762
1763
1764
1765
  		if (err)
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err));
  
  		return SCTP_DISPOSITION_CONSUME;
  	}
a000c01e6   Wei Yongjun   sctp: stop pendin...
1766
1767
  	/* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked
  	 * data. Consider the optional choice of resending of this data.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1768
  	 */
a000c01e6   Wei Yongjun   sctp: stop pendin...
1769
1770
1771
  	sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1772
  	sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
a000c01e6   Wei Yongjun   sctp: stop pendin...
1773
1774
1775
1776
1777
1778
  	/* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue
  	 * and ASCONF-ACK cache.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
  	sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779
1780
1781
  	repl = sctp_make_cookie_ack(new_asoc, chunk);
  	if (!repl)
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
1783
1784
1785
  	/* Report association restart to upper layer. */
  	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
  					     new_asoc->c.sinit_num_ostreams,
  					     new_asoc->c.sinit_max_instreams,
a5a35e767   Vlad Yasevich   [SCTP]: Implement...
1786
  					     NULL, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1787
1788
  	if (!ev)
  		goto nomem_ev;
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1789
1790
  	/* Update the content of current association. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
d3e8e4c11   Jere Leppänen   sctp: Start shutd...
1792
1793
  	if ((sctp_state(asoc, SHUTDOWN_PENDING) ||
  	     sctp_state(asoc, SHUTDOWN_SENT)) &&
bdf6fa52f   Vlad Yasevich   sctp: handle asso...
1794
1795
  	    (sctp_sstate(asoc->base.sk, CLOSING) ||
  	     sock_flag(asoc->base.sk, SOCK_DEAD))) {
d3e8e4c11   Jere Leppänen   sctp: Start shutd...
1796
1797
1798
  		/* If the socket has been closed by user, don't
  		 * transition to ESTABLISHED. Instead trigger SHUTDOWN
  		 * bundled with COOKIE_ACK.
bdf6fa52f   Vlad Yasevich   sctp: handle asso...
1799
1800
1801
  		 */
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  		return sctp_sf_do_9_2_start_shutdown(net, ep, asoc,
145cb2f71   Jere Leppänen   sctp: Fix bundlin...
1802
  						     SCTP_ST_CHUNK(0), repl,
bdf6fa52f   Vlad Yasevich   sctp: handle asso...
1803
1804
1805
1806
1807
1808
  						     commands);
  	} else {
  		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  				SCTP_STATE(SCTP_STATE_ESTABLISHED));
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem_ev:
  	sctp_chunk_free(repl);
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'B')
   *
   * Section 5.2.4
   *   B) In this case, both sides may be attempting to start an association
   *      at about the same time but the peer endpoint started its INIT
   *      after responding to the local endpoint's INIT
   */
  /* This case represents an initialization collision.  */
172a1599b   Xin Long   sctp: remove the ...
1825
1826
  static enum sctp_disposition sctp_sf_do_dupcook_b(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1827
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1828
1829
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
1830
  					struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1831
1832
  					struct sctp_association *new_asoc)
  {
01a992bea   Xin Long   sctp: remove the ...
1833
  	struct sctp_init_chunk *peer_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1834
1835
1836
1837
1838
1839
  	struct sctp_chunk *repl;
  
  	/* new_asoc is a brand-new association, so these are not yet
  	 * side effects--it is safe to run them here.
  	 */
  	peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
de6becdc0   Wei Yongjun   sctp: fix to chec...
1840
  	if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1841
1842
  			       GFP_ATOMIC))
  		goto nomem;
4842a08fb   Xin Long   sctp: init active...
1843
1844
  	if (sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC))
  		goto nomem;
59d8d4434   Xin Long   sctp: delay the a...
1845
1846
  	if (!sctp_auth_chunk_verify(net, chunk, new_asoc))
  		return SCTP_DISPOSITION_DISCARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1847
1848
1849
1850
  	/* Update the content of current association.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_ESTABLISHED));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1851
  	SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1852
1853
1854
1855
1856
1857
1858
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
  
  	repl = sctp_make_cookie_ack(new_asoc, chunk);
  	if (!repl)
  		goto nomem;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1859
1860
1861
1862
1863
1864
  
  	/* RFC 2960 5.1 Normal Establishment of an Association
  	 *
  	 * D) IMPLEMENTATION NOTE: An implementation may choose to
  	 * send the Communication Up notification to the SCTP user
  	 * upon reception of a valid COOKIE ECHO chunk.
07d939677   Vlad Yasevich   [SCTP]: Set assoc...
1865
1866
1867
1868
1869
  	 *
  	 * Sadly, this needs to be implemented as a side-effect, because
  	 * we are not guaranteed to have set the association id of the real
  	 * association and so these notifications need to be delayed until
  	 * the association id is allocated.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1870
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871

07d939677   Vlad Yasevich   [SCTP]: Set assoc...
1872
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_CHANGE, SCTP_U8(SCTP_COMM_UP));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1873
1874
  
  	/* Sockets API Draft Section 5.3.1.6
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
1875
  	 * When a peer sends a Adaptation Layer Indication parameter , SCTP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1876
  	 * delivers this notification to inform the application that of the
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
1877
  	 * peers requested adaptation layer.
07d939677   Vlad Yasevich   [SCTP]: Set assoc...
1878
1879
1880
  	 *
  	 * This also needs to be done as a side effect for the same reason as
  	 * above.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
  	 */
07d939677   Vlad Yasevich   [SCTP]: Set assoc...
1882
1883
  	if (asoc->peer.adaptation_ind)
  		sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1884

30f6ebf65   Xin Long   sctp: add SCTP_AU...
1885
1886
  	if (!asoc->peer.auth_capable)
  		sctp_add_cmd_sf(commands, SCTP_CMD_PEER_NO_AUTH, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1887
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'C')
   *
   * Section 5.2.4
   *  C) In this case, the local endpoint's cookie has arrived late.
   *     Before it arrived, the local endpoint sent an INIT and received an
   *     INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag
   *     but a new tag of its own.
   */
  /* This case represents an initialization collision.  */
172a1599b   Xin Long   sctp: remove the ...
1901
1902
  static enum sctp_disposition sctp_sf_do_dupcook_c(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1903
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1904
1905
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
1906
  					struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
  					struct sctp_association *new_asoc)
  {
  	/* The cookie should be silently discarded.
  	 * The endpoint SHOULD NOT change states and should leave
  	 * any timers running.
  	 */
  	return SCTP_DISPOSITION_DISCARD;
  }
  
  /* Unexpected COOKIE-ECHO handler lost chunk (Table 2, action 'D')
   *
   * Section 5.2.4
   *
   * D) When both local and remote tags match the endpoint should always
   *    enter the ESTABLISHED state, if it has not already done so.
   */
  /* This case represents an initialization collision.  */
172a1599b   Xin Long   sctp: remove the ...
1924
1925
  static enum sctp_disposition sctp_sf_do_dupcook_d(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1926
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1927
1928
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
1929
  					struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1930
1931
  					struct sctp_association *new_asoc)
  {
30f6ebf65   Xin Long   sctp: add SCTP_AU...
1932
  	struct sctp_ulpevent *ev = NULL, *ai_ev = NULL, *auth_ev = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1933
1934
1935
1936
  	struct sctp_chunk *repl;
  
  	/* Clarification from Implementor's Guide:
  	 * D) When both local and remote tags match the endpoint should
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
1937
1938
1939
  	 * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.
  	 * It should stop any cookie timer that may be running and send
  	 * a COOKIE ACK.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1940
  	 */
59d8d4434   Xin Long   sctp: delay the a...
1941
1942
  	if (!sctp_auth_chunk_verify(net, chunk, asoc))
  		return SCTP_DISPOSITION_DISCARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1943
1944
1945
1946
1947
1948
  	/* Don't accidentally move back into established state. */
  	if (asoc->state < SCTP_STATE_ESTABLISHED) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
  		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  				SCTP_STATE(SCTP_STATE_ESTABLISHED));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
1949
  		SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
  		sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
  				SCTP_NULL());
  
  		/* RFC 2960 5.1 Normal Establishment of an Association
  		 *
  		 * D) IMPLEMENTATION NOTE: An implementation may choose
  		 * to send the Communication Up notification to the
  		 * SCTP user upon reception of a valid COOKIE
  		 * ECHO chunk.
  		 */
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1960
  		ev = sctp_ulpevent_make_assoc_change(asoc, 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1961
  					     SCTP_COMM_UP, 0,
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1962
1963
  					     asoc->c.sinit_num_ostreams,
  					     asoc->c.sinit_max_instreams,
9cbcbf4e0   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
1964
  					     NULL, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1965
1966
  		if (!ev)
  			goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1967
1968
  
  		/* Sockets API Draft Section 5.3.1.6
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
1969
  		 * When a peer sends a Adaptation Layer Indication parameter,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1970
  		 * SCTP delivers this notification to inform the application
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
1971
  		 * that of the peers requested adaptation layer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1972
  		 */
0f3fffd8a   Ivan Skytte Jorgensen   [SCTP]: Fix typo ...
1973
1974
  		if (asoc->peer.adaptation_ind) {
  			ai_ev = sctp_ulpevent_make_adaptation_indication(asoc,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1975
  								 GFP_ATOMIC);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1976
  			if (!ai_ev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1977
  				goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1978
  		}
30f6ebf65   Xin Long   sctp: add SCTP_AU...
1979
1980
1981
1982
1983
1984
1985
1986
  
  		if (!asoc->peer.auth_capable) {
  			auth_ev = sctp_ulpevent_make_authkey(asoc, 0,
  							     SCTP_AUTH_NO_AUTH,
  							     GFP_ATOMIC);
  			if (!auth_ev)
  				goto nomem;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1987
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1988

46e16d4b9   Xin Long   sctp: use the old...
1989
  	repl = sctp_make_cookie_ack(asoc, chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1990
1991
  	if (!repl)
  		goto nomem;
2e3216cd5   Vlad Yasevich   sctp: Follow secu...
1992
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
1993
1994
1995
1996
1997
1998
  	if (ev)
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(ev));
  	if (ai_ev)
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  					SCTP_ULPEVENT(ai_ev));
30f6ebf65   Xin Long   sctp: add SCTP_AU...
1999
2000
2001
  	if (auth_ev)
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(auth_ev));
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
2002

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2003
2004
2005
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
30f6ebf65   Xin Long   sctp: add SCTP_AU...
2006
2007
  	if (auth_ev)
  		sctp_ulpevent_free(auth_ev);
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
2008
2009
  	if (ai_ev)
  		sctp_ulpevent_free(ai_ev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
  	if (ev)
  		sctp_ulpevent_free(ev);
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Handle a duplicate COOKIE-ECHO.  This usually means a cookie-carrying
   * chunk was retransmitted and then delayed in the network.
   *
   * Section: 5.2.4 Handle a COOKIE ECHO when a TCB exists
   *
   * Verification Tag: None.  Do cookie validation.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2031
2032
  enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2033
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2034
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2035
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2036
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2037
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2038
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2039
  	struct sctp_association *new_asoc;
172a1599b   Xin Long   sctp: remove the ...
2040
2041
2042
  	struct sctp_chunk *chunk = arg;
  	enum sctp_disposition retval;
  	struct sctp_chunk *err_chk_p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2043
2044
  	int error = 0;
  	char action;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
2046
2047
2048
2049
2050
  
  	/* Make sure that the chunk has a valid length from the protocol
  	 * perspective.  In this case check to make sure we have at least
  	 * enough for the chunk header.  Cookie length verification is
  	 * done later.
  	 */
922dbc5be   Xin Long   sctp: remove the ...
2051
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2052
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2053
2054
2055
2056
2057
  						  commands);
  
  	/* "Decode" the chunk.  We have no optional parameters so we
  	 * are in good shape.
  	 */
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2058
  	chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
62b08083e   Sridhar Samudrala   [SCTP]: Fix panic...
2059
  	if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
922dbc5be   Xin Long   sctp: remove the ...
2060
  					sizeof(struct sctp_chunkhdr)))
62b08083e   Sridhar Samudrala   [SCTP]: Fix panic...
2061
  		goto nomem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
  
  	/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
  	 * of a duplicate COOKIE ECHO match the Verification Tags of the
  	 * current association, consider the State Cookie valid even if
  	 * the lifespan is exceeded.
  	 */
  	new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
  				      &err_chk_p);
  
  	/* FIXME:
  	 * If the re-build failed, what is the proper error path
  	 * from here?
  	 *
  	 * [We should abort the association. --piggy]
  	 */
  	if (!new_asoc) {
  		/* FIXME: Several errors are possible.  A bad cookie should
  		 * be silently discarded, but think about logging it too.
  		 */
  		switch (error) {
  		case -SCTP_IERROR_NOMEM:
  			goto nomem;
  
  		case -SCTP_IERROR_STALE_COOKIE:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2086
  			sctp_send_stale_cookie_err(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2087
  						   err_chk_p);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2088
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2089
2090
  		case -SCTP_IERROR_BAD_SIG:
  		default:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2091
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
3ff50b799   Stephen Hemminger   [NET]: cleanup ex...
2092
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2093
  	}
2277c7cd7   Richard Haines   sctp: Add LSM hooks
2094
2095
  	/* Update socket peer label if first association. */
  	if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
b6631c603   Navid Emamdoost   sctp: Fix memory ...
2096
2097
  					chunk->skb)) {
  		sctp_association_free(new_asoc);
2277c7cd7   Richard Haines   sctp: Add LSM hooks
2098
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
b6631c603   Navid Emamdoost   sctp: Fix memory ...
2099
  	}
2277c7cd7   Richard Haines   sctp: Add LSM hooks
2100

7e0629776   Xin Long   sctp: set new_aso...
2101
2102
  	/* Set temp so that it won't be added into hashtable */
  	new_asoc->temp = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2103
2104
2105
2106
2107
2108
2109
  	/* Compare the tie_tag in cookie with the verification tag of
  	 * current association.
  	 */
  	action = sctp_tietags_compare(new_asoc, asoc);
  
  	switch (action) {
  	case 'A': /* Association restart. */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2110
  		retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2111
2112
2113
2114
  					      new_asoc);
  		break;
  
  	case 'B': /* Collision case B. */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2115
  		retval = sctp_sf_do_dupcook_b(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2116
2117
2118
2119
  					      new_asoc);
  		break;
  
  	case 'C': /* Collision case C. */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2120
  		retval = sctp_sf_do_dupcook_c(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2121
2122
2123
2124
  					      new_asoc);
  		break;
  
  	case 'D': /* Collision case D. */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2125
  		retval = sctp_sf_do_dupcook_d(net, ep, asoc, chunk, commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2126
2127
2128
2129
  					      new_asoc);
  		break;
  
  	default: /* Discard packet for all others. */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2130
  		retval = sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2131
  		break;
3ff50b799   Stephen Hemminger   [NET]: cleanup ex...
2132
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2133
2134
  
  	/* Delete the tempory new association. */
f28156335   Vlad Yasevich   sctp: Use correct...
2135
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2136
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
d5ccd4966   Max Matveev   sctp: deal with m...
2137
2138
2139
2140
2141
  	/* Restore association pointer to provide SCTP command interpeter
  	 * with a valid context in case it needs to manipulate
  	 * the queues */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC,
  			 SCTP_ASOC((struct sctp_association *)asoc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
  	return retval;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Process an ABORT.  (SHUTDOWN-PENDING state)
   *
   * See sctp_sf_do_9_1_abort().
   */
172a1599b   Xin Long   sctp: remove the ...
2153
2154
2155
2156
2157
2158
2159
  enum sctp_disposition sctp_sf_shutdown_pending_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
2161
2162
2163
  {
  	struct sctp_chunk *chunk = arg;
  
  	if (!sctp_vtag_verify_either(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2164
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2165
2166
2167
2168
2169
2170
2171
  
  	/* Make sure that the ABORT chunk has a valid length.
  	 * Since this is an ABORT chunk, we have to discard it
  	 * because of the following text:
  	 * RFC 2960, Section 3.3.7
  	 *    If an endpoint receives an ABORT with a format error or for an
  	 *    association that doesn't exist, it MUST silently discard it.
25985edce   Lucas De Marchi   Fix common misspe...
2172
  	 * Because the length is "invalid", we can't really discard just
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2173
2174
2175
  	 * as we do not know its true length.  So, to be safe, discard the
  	 * packet.
  	 */
441ae65ae   Xin Long   sctp: remove the ...
2176
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2177
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2178

75205f478   Vlad Yasevich   [SCTP]: Implement...
2179
2180
2181
2182
2183
2184
2185
  	/* ADD-IP: Special case for ABORT chunks
  	 * F4)  One special consideration is that ABORT Chunks arriving
  	 * destined to the IP address being deleted MUST be
  	 * ignored (see Section 5.3.1 for further details).
  	 */
  	if (SCTP_ADDR_DEL ==
  		    sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2186
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
75205f478   Vlad Yasevich   [SCTP]: Implement...
2187

245709ec8   Xin Long   sctp: move the fo...
2188
2189
  	if (!sctp_err_chunk_valid(chunk))
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2190
  	return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2191
2192
2193
2194
2195
2196
2197
  }
  
  /*
   * Process an ABORT.  (SHUTDOWN-SENT state)
   *
   * See sctp_sf_do_9_1_abort().
   */
172a1599b   Xin Long   sctp: remove the ...
2198
2199
  enum sctp_disposition sctp_sf_shutdown_sent_abort(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2200
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2201
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2202
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2203
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2204
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2205
2206
2207
2208
  {
  	struct sctp_chunk *chunk = arg;
  
  	if (!sctp_vtag_verify_either(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2209
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2210
2211
2212
2213
2214
2215
2216
  
  	/* Make sure that the ABORT chunk has a valid length.
  	 * Since this is an ABORT chunk, we have to discard it
  	 * because of the following text:
  	 * RFC 2960, Section 3.3.7
  	 *    If an endpoint receives an ABORT with a format error or for an
  	 *    association that doesn't exist, it MUST silently discard it.
25985edce   Lucas De Marchi   Fix common misspe...
2217
  	 * Because the length is "invalid", we can't really discard just
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2218
2219
2220
  	 * as we do not know its true length.  So, to be safe, discard the
  	 * packet.
  	 */
441ae65ae   Xin Long   sctp: remove the ...
2221
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2222
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2223

75205f478   Vlad Yasevich   [SCTP]: Implement...
2224
2225
2226
2227
2228
2229
2230
  	/* ADD-IP: Special case for ABORT chunks
  	 * F4)  One special consideration is that ABORT Chunks arriving
  	 * destined to the IP address being deleted MUST be
  	 * ignored (see Section 5.3.1 for further details).
  	 */
  	if (SCTP_ADDR_DEL ==
  		    sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2231
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
75205f478   Vlad Yasevich   [SCTP]: Implement...
2232

245709ec8   Xin Long   sctp: move the fo...
2233
2234
  	if (!sctp_err_chunk_valid(chunk))
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2235
2236
2237
2238
2239
2240
2241
  	/* Stop the T2-shutdown timer. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  
  	/* Stop the T5-shutdown guard timer.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2242
  	return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2243
2244
2245
2246
2247
2248
2249
  }
  
  /*
   * Process an ABORT.  (SHUTDOWN-ACK-SENT state)
   *
   * See sctp_sf_do_9_1_abort().
   */
172a1599b   Xin Long   sctp: remove the ...
2250
2251
2252
2253
2254
2255
2256
  enum sctp_disposition sctp_sf_shutdown_ack_sent_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2257
2258
2259
2260
  {
  	/* The same T2 timer, so we should be able to use
  	 * common function with the SHUTDOWN-SENT state.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2261
  	return sctp_sf_shutdown_sent_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
  }
  
  /*
   * Handle an Error received in COOKIE_ECHOED state.
   *
   * Only handle the error type of stale COOKIE Error, the other errors will
   * be ignored.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2278
2279
  enum sctp_disposition sctp_sf_cookie_echoed_err(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2280
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2281
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2282
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2283
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2284
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285
2286
  {
  	struct sctp_chunk *chunk = arg;
d8238d9da   Xin Long   sctp: remove the ...
2287
  	struct sctp_errhdr *err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2288
2289
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2290
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2291
2292
2293
2294
  
  	/* Make sure that the ERROR chunk has a valid length.
  	 * The parameter walking depends on this as well.
  	 */
87caeba79   Xin Long   sctp: remove the ...
2295
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_operr_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2296
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2297
2298
2299
2300
2301
2302
2303
2304
2305
  						  commands);
  
  	/* Process the error here */
  	/* FUTURE FIXME:  When PR-SCTP related and other optional
  	 * parms are emitted, this will have to change to handle multiple
  	 * errors.
  	 */
  	sctp_walk_errors(err, chunk->chunk_hdr) {
  		if (SCTP_ERROR_STALE_COOKIE == err->cause)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2306
  			return sctp_sf_do_5_2_6_stale(net, ep, asoc, type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2307
2308
2309
2310
2311
2312
2313
2314
  							arg, commands);
  	}
  
  	/* It is possible to have malformed error causes, and that
  	 * will cause us to end the walk early.  However, since
  	 * we are discarding the packet, there should be no adverse
  	 * affects.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2315
  	return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
  }
  
  /*
   * Handle a Stale COOKIE Error
   *
   * Section: 5.2.6 Handle Stale COOKIE Error
   * If the association is in the COOKIE-ECHOED state, the endpoint may elect
   * one of the following three alternatives.
   * ...
   * 3) Send a new INIT chunk to the endpoint, adding a Cookie
   *    Preservative parameter requesting an extension to the lifetime of
   *    the State Cookie. When calculating the time extension, an
   *    implementation SHOULD use the RTT information measured based on the
   *    previous COOKIE ECHO / ERROR exchange, and should add no more
   *    than 1 second beyond the measured RTT, due to long State Cookie
   *    lifetimes making the endpoint more subject to a replay attack.
   *
   * Verification Tag:  Not explicit, but safe to ignore.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2343
2344
2345
2346
2347
2348
2349
  static enum sctp_disposition sctp_sf_do_5_2_6_stale(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2350
  {
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
2351
  	int attempts = asoc->init_err_counter + 1;
365ddb65e   Xin Long   sctp: remove the ...
2352
2353
2354
  	struct sctp_chunk *chunk = arg, *reply;
  	struct sctp_cookie_preserve_param bht;
  	struct sctp_bind_addr *bp;
d8238d9da   Xin Long   sctp: remove the ...
2355
  	struct sctp_errhdr *err;
365ddb65e   Xin Long   sctp: remove the ...
2356
  	u32 stale;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2357

81845c21d   Vlad Yasevich   [SCTP]: correct t...
2358
  	if (attempts > asoc->max_init_attempts) {
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
2359
2360
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2361
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
dc251b2b1   Al Viro   [SCTP]: SCTP_CMD_...
2362
  				SCTP_PERR(SCTP_ERROR_STALE_COOKIE));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2363
2364
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
d8238d9da   Xin Long   sctp: remove the ...
2365
  	err = (struct sctp_errhdr *)(chunk->skb->data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
  
  	/* When calculating the time extension, an implementation
  	 * SHOULD use the RTT information measured based on the
  	 * previous COOKIE ECHO / ERROR exchange, and should add no
  	 * more than 1 second beyond the measured RTT, due to long
  	 * State Cookie lifetimes making the endpoint more subject to
  	 * a replay attack.
  	 * Measure of Staleness's unit is usec. (1/1000000 sec)
  	 * Suggested Cookie Life-span Increment's unit is msec.
  	 * (1/1000 sec)
  	 * In general, if you use the suggested cookie life, the value
  	 * found in the field of measure of staleness should be doubled
  	 * to give ample time to retransmit the new cookie and thus
  	 * yield a higher probability of success on the reattempt.
  	 */
d8238d9da   Xin Long   sctp: remove the ...
2381
  	stale = ntohl(*(__be32 *)((u8 *)err + sizeof(*err)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
  	stale = (stale * 2) / 1000;
  
  	bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE;
  	bht.param_hdr.length = htons(sizeof(bht));
  	bht.lifespan_increment = htonl(stale);
  
  	/* Build that new INIT chunk.  */
  	bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
  	reply = sctp_make_init(asoc, bp, GFP_ATOMIC, sizeof(bht));
  	if (!reply)
  		goto nomem;
  
  	sctp_addto_chunk(reply, sizeof(bht), &bht);
  
  	/* Clear peer's init_tag cached in assoc as we are sending a new INIT */
  	sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
  
  	/* Stop pending T3-rtx and heartbeat timers */
  	sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
  
  	/* Delete non-primary peer ip addresses since we are transitioning
  	 * back to the COOKIE-WAIT state
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_DEL_NON_PRIMARY, SCTP_NULL());
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2407
2408
  	/* If we've sent any data bundled with COOKIE-ECHO we will need to
  	 * resend
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2409
  	 */
b6157d8e0   Vlad Yasevich   SCTP: Fix differe...
2410
  	sctp_add_cmd_sf(commands, SCTP_CMD_T1_RETRAN,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2411
2412
2413
2414
2415
  			SCTP_TRANSPORT(asoc->peer.primary_path));
  
  	/* Cast away the const modifier, as we want to just
  	 * rerun it through as a sideffect.
  	 */
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
2416
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_INC, SCTP_NULL());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Process an ABORT.
   *
   * Section: 9.1
   * After checking the Verification Tag, the receiving endpoint shall
   * remove the association from its record, and shall report the
   * termination to its upper layer.
   *
   * Verification Tag: 8.5.1 Exceptions in Verification Tag Rules
   * B) Rules for packet carrying ABORT:
   *
   *  - The endpoint shall always fill in the Verification Tag field of the
   *    outbound packet with the destination endpoint's tag value if it
   *    is known.
   *
   *  - If the ABORT is sent in response to an OOTB packet, the endpoint
   *    MUST follow the procedure described in Section 8.4.
   *
   *  - The receiver MUST accept the packet if the Verification Tag
   *    matches either its own tag, OR the tag of its peer. Otherwise, the
   *    receiver MUST silently discard the packet and take no further
   *    action.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2464
2465
  enum sctp_disposition sctp_sf_do_9_1_abort(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2466
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2467
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2468
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2469
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2470
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2471
2472
  {
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2473
2474
  
  	if (!sctp_vtag_verify_either(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2475
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2476
2477
2478
2479
2480
2481
2482
  
  	/* Make sure that the ABORT chunk has a valid length.
  	 * Since this is an ABORT chunk, we have to discard it
  	 * because of the following text:
  	 * RFC 2960, Section 3.3.7
  	 *    If an endpoint receives an ABORT with a format error or for an
  	 *    association that doesn't exist, it MUST silently discard it.
25985edce   Lucas De Marchi   Fix common misspe...
2483
  	 * Because the length is "invalid", we can't really discard just
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2484
2485
2486
  	 * as we do not know its true length.  So, to be safe, discard the
  	 * packet.
  	 */
441ae65ae   Xin Long   sctp: remove the ...
2487
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2488
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2489

75205f478   Vlad Yasevich   [SCTP]: Implement...
2490
2491
2492
2493
2494
2495
2496
  	/* ADD-IP: Special case for ABORT chunks
  	 * F4)  One special consideration is that ABORT Chunks arriving
  	 * destined to the IP address being deleted MUST be
  	 * ignored (see Section 5.3.1 for further details).
  	 */
  	if (SCTP_ADDR_DEL ==
  		    sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2497
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
75205f478   Vlad Yasevich   [SCTP]: Implement...
2498

245709ec8   Xin Long   sctp: move the fo...
2499
2500
  	if (!sctp_err_chunk_valid(chunk))
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2501
  	return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
75205f478   Vlad Yasevich   [SCTP]: Implement...
2502
  }
172a1599b   Xin Long   sctp: remove the ...
2503
2504
  static enum sctp_disposition __sctp_sf_do_9_1_abort(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2505
  					const struct sctp_endpoint *ep,
75205f478   Vlad Yasevich   [SCTP]: Implement...
2506
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2507
  					const union sctp_subtype type,
75205f478   Vlad Yasevich   [SCTP]: Implement...
2508
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2509
  					struct sctp_cmd_seq *commands)
75205f478   Vlad Yasevich   [SCTP]: Implement...
2510
  {
172a1599b   Xin Long   sctp: remove the ...
2511
  	__be16 error = SCTP_ERROR_NO_ERROR;
75205f478   Vlad Yasevich   [SCTP]: Implement...
2512
  	struct sctp_chunk *chunk = arg;
95c961747   Eric Dumazet   net: cleanup unsi...
2513
  	unsigned int len;
75205f478   Vlad Yasevich   [SCTP]: Implement...
2514

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2515
2516
  	/* See if we have an error cause code in the chunk.  */
  	len = ntohs(chunk->chunk_hdr->length);
245709ec8   Xin Long   sctp: move the fo...
2517
  	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
d8238d9da   Xin Long   sctp: remove the ...
2518
  		error = ((struct sctp_errhdr *)chunk->skb->data)->cause;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2519

8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
2520
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2521
  	/* ASSOC_FAILED will DELETE_TCB. */
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
2522
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_PERR(error));
b01a24078   Eric W. Biederman   sctp: Make the mi...
2523
2524
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2525
2526
2527
2528
2529
2530
2531
2532
2533
  
  	return SCTP_DISPOSITION_ABORT;
  }
  
  /*
   * Process an ABORT.  (COOKIE-WAIT state)
   *
   * See sctp_sf_do_9_1_abort() above.
   */
172a1599b   Xin Long   sctp: remove the ...
2534
2535
2536
2537
2538
2539
2540
  enum sctp_disposition sctp_sf_cookie_wait_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2541
  {
172a1599b   Xin Long   sctp: remove the ...
2542
  	__be16 error = SCTP_ERROR_NO_ERROR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2543
  	struct sctp_chunk *chunk = arg;
95c961747   Eric Dumazet   net: cleanup unsi...
2544
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2545
2546
  
  	if (!sctp_vtag_verify_either(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2547
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2548
2549
2550
2551
2552
2553
2554
  
  	/* Make sure that the ABORT chunk has a valid length.
  	 * Since this is an ABORT chunk, we have to discard it
  	 * because of the following text:
  	 * RFC 2960, Section 3.3.7
  	 *    If an endpoint receives an ABORT with a format error or for an
  	 *    association that doesn't exist, it MUST silently discard it.
25985edce   Lucas De Marchi   Fix common misspe...
2555
  	 * Because the length is "invalid", we can't really discard just
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2556
2557
2558
  	 * as we do not know its true length.  So, to be safe, discard the
  	 * packet.
  	 */
441ae65ae   Xin Long   sctp: remove the ...
2559
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_abort_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2560
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2561
2562
2563
2564
  
  	/* See if we have an error cause code in the chunk.  */
  	len = ntohs(chunk->chunk_hdr->length);
  	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
d8238d9da   Xin Long   sctp: remove the ...
2565
  		error = ((struct sctp_errhdr *)chunk->skb->data)->cause;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2566

24cb81a6a   Eric W. Biederman   sctp: Push struct...
2567
  	return sctp_stop_t1_and_abort(net, commands, error, ECONNREFUSED, asoc,
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
2568
  				      chunk->transport);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2569
2570
2571
2572
2573
  }
  
  /*
   * Process an incoming ICMP as an ABORT.  (COOKIE-WAIT state)
   */
172a1599b   Xin Long   sctp: remove the ...
2574
2575
  enum sctp_disposition sctp_sf_cookie_wait_icmp_abort(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2576
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2577
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
2578
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2579
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
2580
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2581
  {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2582
  	return sctp_stop_t1_and_abort(net, commands, SCTP_ERROR_NO_ERROR,
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
2583
  				      ENOPROTOOPT, asoc,
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
2584
  				      (struct sctp_transport *)arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2585
2586
2587
2588
2589
  }
  
  /*
   * Process an ABORT.  (COOKIE-ECHOED state)
   */
172a1599b   Xin Long   sctp: remove the ...
2590
2591
2592
2593
2594
2595
2596
  enum sctp_disposition sctp_sf_cookie_echoed_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2597
2598
2599
2600
  {
  	/* There is a single T1 timer, so we should be able to use
  	 * common function with the COOKIE-WAIT state.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2601
  	return sctp_sf_cookie_wait_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2602
2603
2604
2605
2606
2607
2608
  }
  
  /*
   * Stop T1 timer and abort association with "INIT failed".
   *
   * This is common code called by several sctp_sf_*_abort() functions above.
   */
172a1599b   Xin Long   sctp: remove the ...
2609
2610
2611
2612
2613
2614
  static enum sctp_disposition sctp_stop_t1_and_abort(
  					struct net *net,
  					struct sctp_cmd_seq *commands,
  					__be16 error, int sk_err,
  					const struct sctp_association *asoc,
  					struct sctp_transport *transport)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2615
  {
bb33381d0   Daniel Borkmann   net: sctp: rework...
2616
2617
  	pr_debug("%s: ABORT received (INIT)
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2618
2619
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_CLOSED));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2620
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2621
2622
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
2623
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2624
2625
  	/* CMD_INIT_FAILED will DELETE_TCB. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
dc251b2b1   Al Viro   [SCTP]: SCTP_CMD_...
2626
  			SCTP_PERR(error));
bb33381d0   Daniel Borkmann   net: sctp: rework...
2627

3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
2628
  	return SCTP_DISPOSITION_ABORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
  }
  
  /*
   * sctp_sf_do_9_2_shut
   *
   * Section: 9.2
   * Upon the reception of the SHUTDOWN, the peer endpoint shall
   *  - enter the SHUTDOWN-RECEIVED state,
   *
   *  - stop accepting new data from its SCTP user
   *
   *  - verify, by checking the Cumulative TSN Ack field of the chunk,
   *    that all its outstanding DATA chunks have been received by the
   *    SHUTDOWN sender.
   *
   * Once an endpoint as reached the SHUTDOWN-RECEIVED state it MUST NOT
   * send a SHUTDOWN in response to a ULP request. And should discard
   * subsequent SHUTDOWN chunks.
   *
   * If there are still outstanding DATA chunks left, the SHUTDOWN
   * receiver shall continue to follow normal data transmission
   * procedures defined in Section 6 until all outstanding DATA chunks
   * are acknowledged; however, the SHUTDOWN receiver MUST NOT accept
   * new data from its SCTP user.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2664
2665
2666
2667
2668
2669
2670
2671
2672
  enum sctp_disposition sctp_sf_do_9_2_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
  {
  	enum sctp_disposition disposition;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2673
  	struct sctp_chunk *chunk = arg;
e61e4055b   Xin Long   sctp: remove the ...
2674
  	struct sctp_shutdownhdr *sdh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2675
  	struct sctp_ulpevent *ev;
df10eec47   Wei Yongjun   sctp: Add check f...
2676
  	__u32 ctsn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2677
2678
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2679
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2680
2681
  
  	/* Make sure that the SHUTDOWN chunk has a valid length. */
ac23e6813   Xin Long   sctp: fix the nam...
2682
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2683
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2684
2685
2686
  						  commands);
  
  	/* Convert the elaborate header.  */
e61e4055b   Xin Long   sctp: remove the ...
2687
2688
  	sdh = (struct sctp_shutdownhdr *)chunk->skb->data;
  	skb_pull(chunk->skb, sizeof(*sdh));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2689
  	chunk->subh.shutdown_hdr = sdh;
df10eec47   Wei Yongjun   sctp: Add check f...
2690
  	ctsn = ntohl(sdh->cum_tsn_ack);
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2691
  	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
2692
2693
2694
  		pr_debug("%s: ctsn:%x, ctsn_ack_point:%x
  ", __func__, ctsn,
  			 asoc->ctsn_ack_point);
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2695
2696
  		return SCTP_DISPOSITION_DISCARD;
  	}
df10eec47   Wei Yongjun   sctp: Add check f...
2697
2698
2699
2700
2701
  	/* If Cumulative TSN Ack beyond the max tsn currently
  	 * send, terminating the association and respond to the
  	 * sender with an ABORT.
  	 */
  	if (!TSN_lt(ctsn, asoc->next_tsn))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2702
  		return sctp_sf_violation_ctsn(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2703

eb0e00768   Sridhar Samudrala   [SCTP]: Fix SCTP_...
2704
2705
2706
2707
2708
2709
2710
  	/* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
  	 * When a peer sends a SHUTDOWN, SCTP delivers this notification to
  	 * inform the application that it should cease sending data.
  	 */
  	ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
  	if (!ev) {
  		disposition = SCTP_DISPOSITION_NOMEM;
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2711
  		goto out;
eb0e00768   Sridhar Samudrala   [SCTP]: Fix SCTP_...
2712
2713
  	}
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
  	/* Upon the reception of the SHUTDOWN, the peer endpoint shall
  	 *  - enter the SHUTDOWN-RECEIVED state,
  	 *  - stop accepting new data from its SCTP user
  	 *
  	 * [This is implicit in the new state.]
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_SHUTDOWN_RECEIVED));
  	disposition = SCTP_DISPOSITION_CONSUME;
  
  	if (sctp_outq_is_empty(&asoc->outqueue)) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2725
  		disposition = sctp_sf_do_9_2_shutdown_ack(net, ep, asoc, type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
  							  arg, commands);
  	}
  
  	if (SCTP_DISPOSITION_NOMEM == disposition)
  		goto out;
  
  	/*  - verify, by checking the Cumulative TSN Ack field of the
  	 *    chunk, that all its outstanding DATA chunks have been
  	 *    received by the SHUTDOWN sender.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
2178eda82   Al Viro   [SCTP]: SCTP_CMD_...
2737
  			SCTP_BE32(chunk->subh.shutdown_hdr->cum_tsn_ack));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2738

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2739
2740
2741
  out:
  	return disposition;
  }
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2742
2743
2744
2745
2746
2747
2748
2749
  /*
   * sctp_sf_do_9_2_shut_ctsn
   *
   * Once an endpoint has reached the SHUTDOWN-RECEIVED state,
   * it MUST NOT send a SHUTDOWN in response to a ULP request.
   * The Cumulative TSN Ack of the received SHUTDOWN chunk
   * MUST be processed.
   */
172a1599b   Xin Long   sctp: remove the ...
2750
2751
2752
2753
2754
2755
2756
  enum sctp_disposition sctp_sf_do_9_2_shut_ctsn(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2757
2758
  {
  	struct sctp_chunk *chunk = arg;
e61e4055b   Xin Long   sctp: remove the ...
2759
  	struct sctp_shutdownhdr *sdh;
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2760
  	__u32 ctsn;
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2761
2762
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2763
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2764
2765
  
  	/* Make sure that the SHUTDOWN chunk has a valid length. */
ac23e6813   Xin Long   sctp: fix the nam...
2766
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2767
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2768
  						  commands);
e61e4055b   Xin Long   sctp: remove the ...
2769
  	sdh = (struct sctp_shutdownhdr *)chunk->skb->data;
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2770
2771
2772
  	ctsn = ntohl(sdh->cum_tsn_ack);
  
  	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
2773
2774
2775
  		pr_debug("%s: ctsn:%x, ctsn_ack_point:%x
  ", __func__, ctsn,
  			 asoc->ctsn_ack_point);
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2776
2777
  		return SCTP_DISPOSITION_DISCARD;
  	}
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2778
2779
2780
2781
2782
  
  	/* If Cumulative TSN Ack beyond the max tsn currently
  	 * send, terminating the association and respond to the
  	 * sender with an ABORT.
  	 */
a2f36eec5   Wei Yongjun   sctp: drop SHUTDO...
2783
  	if (!TSN_lt(ctsn, asoc->next_tsn))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2784
  		return sctp_sf_violation_ctsn(net, ep, asoc, type, arg, commands);
2e3f92dad   Wei Yongjun   sctp: Fix to hand...
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
  
  	/* verify, by checking the Cumulative TSN Ack field of the
  	 * chunk, that all its outstanding DATA chunks have been
  	 * received by the SHUTDOWN sender.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
  			SCTP_BE32(sdh->cum_tsn_ack));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2795
2796
2797
2798
2799
2800
2801
  /* RFC 2960 9.2
   * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
   * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
   * transport addresses (either in the IP addresses or in the INIT chunk)
   * that belong to this association, it should discard the INIT chunk and
   * retransmit the SHUTDOWN ACK chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2802
2803
2804
2805
2806
2807
2808
  enum sctp_disposition sctp_sf_do_9_2_reshutack(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2809
  {
172a1599b   Xin Long   sctp: remove the ...
2810
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2811
  	struct sctp_chunk *reply;
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
2812
  	/* Make sure that the chunk has a valid length */
922dbc5be   Xin Long   sctp: remove the ...
2813
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2814
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
2815
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
  	/* Since we are not going to really process this INIT, there
  	 * is no point in verifying chunk boundries.  Just generate
  	 * the SHUTDOWN ACK.
  	 */
  	reply = sctp_make_shutdown_ack(asoc, chunk);
  	if (NULL == reply)
  		goto nomem;
  
  	/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
  	 * the T2-SHUTDOWN timer.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
  
  	/* and restart the T2-shutdown timer. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  
  	return SCTP_DISPOSITION_CONSUME;
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * sctp_sf_do_ecn_cwr
   *
   * Section:  Appendix A: Explicit Congestion Notification
   *
   * CWR:
   *
   * RFC 2481 details a specific bit for a sender to send in the header of
   * its next outbound TCP segment to indicate to its peer that it has
   * reduced its congestion window.  This is termed the CWR bit.  For
   * SCTP the same indication is made by including the CWR chunk.
   * This chunk contains one data element, i.e. the TSN number that
   * was sent in the ECNE chunk.  This element represents the lowest
   * TSN number in the datagram that was originally marked with the
   * CE bit.
   *
   * Verification Tag: 8.5 Verification Tag [Normal verification]
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2865
2866
2867
2868
2869
2870
  enum sctp_disposition sctp_sf_do_ecn_cwr(struct net *net,
  					 const struct sctp_endpoint *ep,
  					 const struct sctp_association *asoc,
  					 const union sctp_subtype type,
  					 void *arg,
  					 struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2871
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2872
  	struct sctp_chunk *chunk = arg;
65f771054   Xin Long   sctp: remove the ...
2873
  	struct sctp_cwrhdr *cwr;
34bcca283   Al Viro   [SCTP]: Even more...
2874
  	u32 lowest_tsn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2875
2876
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2877
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2878

b515fd275   Xin Long   sctp: remove the ...
2879
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_ecne_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2880
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2881
  						  commands);
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2882

65f771054   Xin Long   sctp: remove the ...
2883
2884
  	cwr = (struct sctp_cwrhdr *)chunk->skb->data;
  	skb_pull(chunk->skb, sizeof(*cwr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2885

34bcca283   Al Viro   [SCTP]: Even more...
2886
  	lowest_tsn = ntohl(cwr->lowest_tsn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2887
2888
  
  	/* Does this CWR ack the last sent congestion notification? */
34bcca283   Al Viro   [SCTP]: Even more...
2889
  	if (TSN_lte(asoc->last_ecne_tsn, lowest_tsn)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2890
2891
2892
  		/* Stop sending ECNE. */
  		sctp_add_cmd_sf(commands,
  				SCTP_CMD_ECN_CWR,
34bcca283   Al Viro   [SCTP]: Even more...
2893
  				SCTP_U32(lowest_tsn));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
  	}
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * sctp_sf_do_ecne
   *
   * Section:  Appendix A: Explicit Congestion Notification
   *
   * ECN-Echo
   *
   * RFC 2481 details a specific bit for a receiver to send back in its
   * TCP acknowledgements to notify the sender of the Congestion
   * Experienced (CE) bit having arrived from the network.  For SCTP this
   * same indication is made by including the ECNE chunk.  This chunk
   * contains one data element, i.e. the lowest TSN associated with the IP
   * datagram marked with the CE bit.....
   *
   * Verification Tag: 8.5 Verification Tag [Normal verification]
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2921
2922
2923
2924
2925
  enum sctp_disposition sctp_sf_do_ecne(struct net *net,
  				      const struct sctp_endpoint *ep,
  				      const struct sctp_association *asoc,
  				      const union sctp_subtype type,
  				      void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2926
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2927
  	struct sctp_chunk *chunk = arg;
1fb6d83bd   Xin Long   sctp: remove the ...
2928
  	struct sctp_ecnehdr *ecne;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2929
2930
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2931
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2932

b515fd275   Xin Long   sctp: remove the ...
2933
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_ecne_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2934
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2935
  						  commands);
1fb6d83bd   Xin Long   sctp: remove the ...
2936
2937
  	ecne = (struct sctp_ecnehdr *)chunk->skb->data;
  	skb_pull(chunk->skb, sizeof(*ecne));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
  
  	/* If this is a newer ECNE than the last CWR packet we sent out */
  	sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE,
  			SCTP_U32(ntohl(ecne->lowest_tsn)));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * Section: 6.2  Acknowledgement on Reception of DATA Chunks
   *
   * The SCTP endpoint MUST always acknowledge the reception of each valid
   * DATA chunk.
   *
   * The guidelines on delayed acknowledgement algorithm specified in
   * Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an
   * acknowledgement SHOULD be generated for at least every second packet
   * (not every second DATA chunk) received, and SHOULD be generated within
   * 200 ms of the arrival of any unacknowledged DATA chunk. In some
   * situations it may be beneficial for an SCTP transmitter to be more
   * conservative than the algorithms detailed in this document allow.
   * However, an SCTP transmitter MUST NOT be more aggressive than the
   * following algorithms allow.
   *
   * A SCTP receiver MUST NOT generate more than one SACK for every
   * incoming packet, other than to update the offered window as the
   * receiving application consumes new data.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
2976
2977
2978
2979
2980
2981
  enum sctp_disposition sctp_sf_eat_data_6_2(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2982
  {
c488b7704   Xin Long   sctp: remove the ...
2983
  	union sctp_arg force = SCTP_NOFORCE();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2984
2985
2986
2987
2988
2989
  	struct sctp_chunk *chunk = arg;
  	int error;
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2990
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
2991
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2992

9d4ceaf15   Xin Long   sctp: implement v...
2993
  	if (!sctp_chunk_length_valid(chunk, sctp_datachk_len(&asoc->stream)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
2994
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2995
  						  commands);
cb3f837ba   wangweidong   sctp: fix checkpa...
2996
  	error = sctp_eat_data(asoc, chunk, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2997
2998
2999
3000
3001
  	switch (error) {
  	case SCTP_IERROR_NO_ERROR:
  		break;
  	case SCTP_IERROR_HIGH_TSN:
  	case SCTP_IERROR_BAD_STREAM:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3002
  		SCTP_INC_STATS(net, SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3003
3004
3005
  		goto discard_noforce;
  	case SCTP_IERROR_DUP_TSN:
  	case SCTP_IERROR_IGNORE_TSN:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3006
  		SCTP_INC_STATS(net, SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3007
3008
  		goto discard_force;
  	case SCTP_IERROR_NO_DATA:
649621e3d   Marcelo Ricardo Leitner   sctp: fix use-aft...
3009
  		return SCTP_DISPOSITION_ABORT;
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
3010
  	case SCTP_IERROR_PROTO_VIOLATION:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3011
  		return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
3583df1a3   Xin Long   sctp: remove the ...
3012
  					       (u8 *)chunk->subh.data_hdr,
9d4ceaf15   Xin Long   sctp: implement v...
3013
  					       sctp_datahdr_len(&asoc->stream));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3014
3015
3016
  	default:
  		BUG();
  	}
6dc7694f9   Wei Yongjun   sctp: implement t...
3017
3018
  	if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM)
  		force = SCTP_FORCE();
9f70f46bd   Neil Horman   sctp: properly la...
3019
  	if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
  	}
  
  	/* If this is the last chunk in a packet, we need to count it
  	 * toward sack generation.  Note that we need to SACK every
  	 * OTHER packet containing data chunks, EVEN IF WE DISCARD
  	 * THEM.  We elect to NOT generate SACK's if the chunk fails
  	 * the verification tag test.
  	 *
  	 * RFC 2960 6.2 Acknowledgement on Reception of DATA Chunks
  	 *
  	 * The SCTP endpoint MUST always acknowledge the reception of
  	 * each valid DATA chunk.
  	 *
  	 * The guidelines on delayed acknowledgement algorithm
  	 * specified in  Section 4.2 of [RFC2581] SHOULD be followed.
  	 * Specifically, an acknowledgement SHOULD be generated for at
  	 * least every second packet (not every second DATA chunk)
  	 * received, and SHOULD be generated within 200 ms of the
  	 * arrival of any unacknowledged DATA chunk.  In some
  	 * situations it may be beneficial for an SCTP transmitter to
  	 * be more conservative than the algorithms detailed in this
  	 * document allow. However, an SCTP transmitter MUST NOT be
  	 * more aggressive than the following algorithms allow.
  	 */
52ccb8e90   Frank Filz   [SCTP]: Update SC...
3046
  	if (chunk->end_of_packet)
6dc7694f9   Wei Yongjun   sctp: implement t...
3047
  		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3048

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
  	return SCTP_DISPOSITION_CONSUME;
  
  discard_force:
  	/* RFC 2960 6.2 Acknowledgement on Reception of DATA Chunks
  	 *
  	 * When a packet arrives with duplicate DATA chunk(s) and with
  	 * no new DATA chunk(s), the endpoint MUST immediately send a
  	 * SACK with no delay.  If a packet arrives with duplicate
  	 * DATA chunk(s) bundled with new DATA chunks, the endpoint
  	 * MAY immediately send a SACK.  Normally receipt of duplicate
  	 * DATA chunks will occur when the original SACK chunk was lost
  	 * and the peer's RTO has expired.  The duplicate TSN number(s)
  	 * SHOULD be reported in the SACK as duplicate.
  	 */
  	/* In our case, we split the MAY SACK advice up whether or not
  	 * the last chunk is a duplicate.'
  	 */
  	if (chunk->end_of_packet)
  		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
  	return SCTP_DISPOSITION_DISCARD;
  
  discard_noforce:
52ccb8e90   Frank Filz   [SCTP]: Update SC...
3071
  	if (chunk->end_of_packet)
6dc7694f9   Wei Yongjun   sctp: implement t...
3072
  		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3073

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3074
  	return SCTP_DISPOSITION_DISCARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
  }
  
  /*
   * sctp_sf_eat_data_fast_4_4
   *
   * Section: 4 (4)
   * (4) In SHUTDOWN-SENT state the endpoint MUST acknowledge any received
   *    DATA chunks without delay.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
3093
3094
3095
3096
3097
3098
3099
  enum sctp_disposition sctp_sf_eat_data_fast_4_4(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3100
3101
3102
3103
3104
3105
3106
  {
  	struct sctp_chunk *chunk = arg;
  	int error;
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3107
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3108
  	}
9d4ceaf15   Xin Long   sctp: implement v...
3109
  	if (!sctp_chunk_length_valid(chunk, sctp_datachk_len(&asoc->stream)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3110
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3111
  						  commands);
cb3f837ba   wangweidong   sctp: fix checkpa...
3112
  	error = sctp_eat_data(asoc, chunk, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3113
3114
3115
3116
3117
3118
3119
3120
  	switch (error) {
  	case SCTP_IERROR_NO_ERROR:
  	case SCTP_IERROR_HIGH_TSN:
  	case SCTP_IERROR_DUP_TSN:
  	case SCTP_IERROR_IGNORE_TSN:
  	case SCTP_IERROR_BAD_STREAM:
  		break;
  	case SCTP_IERROR_NO_DATA:
649621e3d   Marcelo Ricardo Leitner   sctp: fix use-aft...
3121
  		return SCTP_DISPOSITION_ABORT;
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
3122
  	case SCTP_IERROR_PROTO_VIOLATION:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3123
  		return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
3583df1a3   Xin Long   sctp: remove the ...
3124
  					       (u8 *)chunk->subh.data_hdr,
9d4ceaf15   Xin Long   sctp: implement v...
3125
  					       sctp_datahdr_len(&asoc->stream));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
  	default:
  		BUG();
  	}
  
  	/* Go a head and force a SACK, since we are shutting down. */
  
  	/* Implementor's Guide.
  	 *
  	 * While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
  	 * respond to each received packet containing one or more DATA chunk(s)
  	 * with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer
  	 */
  	if (chunk->end_of_packet) {
  		/* We must delay the chunk creation since the cumulative
  		 * TSN has not been updated yet.
  		 */
  		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SHUTDOWN, SCTP_NULL());
  		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * Section: 6.2  Processing a Received SACK
   * D) Any time a SACK arrives, the endpoint performs the following:
   *
   *     i) If Cumulative TSN Ack is less than the Cumulative TSN Ack Point,
   *     then drop the SACK.   Since Cumulative TSN Ack is monotonically
   *     increasing, a SACK whose Cumulative TSN Ack is less than the
   *     Cumulative TSN Ack Point indicates an out-of-order SACK.
   *
   *     ii) Set rwnd equal to the newly received a_rwnd minus the number
   *     of bytes still outstanding after processing the Cumulative TSN Ack
   *     and the Gap Ack Blocks.
   *
   *     iii) If the SACK is missing a TSN that was previously
   *     acknowledged via a Gap Ack Block (e.g., the data receiver
   *     reneged on the data), then mark the corresponding DATA chunk
   *     as available for retransmit:  Mark it as missing for fast
   *     retransmit as described in Section 7.2.4 and if no retransmit
   *     timer is running for the destination address to which the DATA
   *     chunk was originally transmitted, then T3-rtx is started for
   *     that destination address.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
3182
3183
3184
3185
3186
3187
  enum sctp_disposition sctp_sf_eat_sack_6_2(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3188
3189
  {
  	struct sctp_chunk *chunk = arg;
787310859   Xin Long   sctp: remove the ...
3190
  	struct sctp_sackhdr *sackh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3191
3192
3193
  	__u32 ctsn;
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3194
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3195
3196
  
  	/* Make sure that the SACK chunk has a valid length. */
d4d6c6148   Xin Long   sctp: remove the ...
3197
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_sack_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3198
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3199
3200
3201
3202
3203
3204
  						  commands);
  
  	/* Pull the SACK chunk from the data buffer */
  	sackh = sctp_sm_pull_sack(chunk);
  	/* Was this a bogus SACK? */
  	if (!sackh)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3205
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3206
3207
  	chunk->subh.sack_hdr = sackh;
  	ctsn = ntohl(sackh->cum_tsn_ack);
356b23c07   Kevin Kou   sctp: do trace_sc...
3208
3209
3210
3211
3212
3213
3214
3215
  	/* If Cumulative TSN Ack beyond the max tsn currently
  	 * send, terminating the association and respond to the
  	 * sender with an ABORT.
  	 */
  	if (TSN_lte(asoc->next_tsn, ctsn))
  		return sctp_sf_violation_ctsn(net, ep, asoc, type, arg, commands);
  
  	trace_sctp_probe(ep, asoc, chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3216
3217
3218
3219
3220
3221
3222
  	/* i) If Cumulative TSN Ack is less than the Cumulative TSN
  	 *     Ack Point, then drop the SACK.  Since Cumulative TSN
  	 *     Ack is monotonically increasing, a SACK whose
  	 *     Cumulative TSN Ack is less than the Cumulative TSN Ack
  	 *     Point indicates an out-of-order SACK.
  	 */
  	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
3223
3224
3225
  		pr_debug("%s: ctsn:%x, ctsn_ack_point:%x
  ", __func__, ctsn,
  			 asoc->ctsn_ack_point);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3226
3227
3228
3229
  		return SCTP_DISPOSITION_DISCARD;
  	}
  
  	/* Return this SACK for further processing.  */
edfee0339   Nicolas Dichtel   sctp: check src a...
3230
  	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_CHUNK(chunk));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
  
  	/* Note: We do the rest of the work on the PROCESS_SACK
  	 * sideeffect.
  	 */
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * Generate an ABORT in response to a packet.
   *
047a2428a   Jerome Forissier   [SCTP] Implement ...
3241
   * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3242
   *
047a2428a   Jerome Forissier   [SCTP] Implement ...
3243
3244
3245
3246
3247
3248
3249
3250
   * 8) The receiver should respond to the sender of the OOTB packet with
   *    an ABORT.  When sending the ABORT, the receiver of the OOTB packet
   *    MUST fill in the Verification Tag field of the outbound packet
   *    with the value found in the Verification Tag field of the OOTB
   *    packet and set the T-bit in the Chunk Flags to indicate that the
   *    Verification Tag is reflected.  After sending this ABORT, the
   *    receiver of the OOTB packet shall discard the OOTB packet and take
   *    no further action.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3251
3252
3253
3254
3255
   *
   * Verification Tag:
   *
   * The return value is the disposition of the chunk.
  */
172a1599b   Xin Long   sctp: remove the ...
3256
3257
  static enum sctp_disposition sctp_sf_tabort_8_4_8(
  					struct net *net,
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3258
  					const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3259
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
3260
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3261
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
3262
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3263
3264
3265
3266
  {
  	struct sctp_packet *packet = NULL;
  	struct sctp_chunk *chunk = arg;
  	struct sctp_chunk *abort;
2ce955035   Eric W. Biederman   sctp: Make the ct...
3267
  	packet = sctp_ootb_pkt_new(net, asoc, chunk);
eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3268
3269
  	if (!packet)
  		return SCTP_DISPOSITION_NOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3270

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3271
3272
3273
3274
3275
3276
3277
3278
  	/* Make an ABORT. The T bit will be set if the asoc
  	 * is NULL.
  	 */
  	abort = sctp_make_abort(asoc, chunk, 0);
  	if (!abort) {
  		sctp_ootb_pkt_free(packet);
  		return SCTP_DISPOSITION_NOMEM;
  	}
047a2428a   Jerome Forissier   [SCTP] Implement ...
3279

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3280
3281
3282
  	/* Reflect vtag if T-Bit is set */
  	if (sctp_test_T_bit(abort))
  		packet->vtag = ntohl(chunk->sctp_hdr->vtag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3283

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3284
3285
  	/* Set the skb to the belonging sock for accounting.  */
  	abort->skb->sk = ep->base.sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3286

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3287
  	sctp_packet_append_chunk(packet, abort);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3288

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3289
3290
  	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  			SCTP_PACKET(packet));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3291

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3292
  	SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3293

eab59075d   Marcelo Ricardo Leitner   sctp: reduce inde...
3294
3295
  	sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
  }
  
  /*
   * Received an ERROR chunk from peer.  Generate SCTP_REMOTE_ERROR
   * event as ULP notification for each cause included in the chunk.
   *
   * API 5.3.1.3 - SCTP_REMOTE_ERROR
   *
   * The return value is the disposition of the chunk.
  */
172a1599b   Xin Long   sctp: remove the ...
3306
3307
3308
3309
3310
3311
  enum sctp_disposition sctp_sf_operr_notify(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3312
3313
  {
  	struct sctp_chunk *chunk = arg;
d8238d9da   Xin Long   sctp: remove the ...
3314
  	struct sctp_errhdr *err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3315
3316
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3317
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3318
3319
  
  	/* Make sure that the ERROR chunk has a valid length. */
87caeba79   Xin Long   sctp: remove the ...
3320
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_operr_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3321
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3322
  						  commands);
8a00be1c8   Shan Wei   sctp: check param...
3323
3324
  	sctp_walk_errors(err, chunk->chunk_hdr);
  	if ((void *)err != (void *)chunk->chunk_end)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3325
  		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
8a00be1c8   Shan Wei   sctp: check param...
3326
  						  (void *)err, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3327

3df267873   Wei Yongjun   sctp: fix kernel ...
3328
3329
  	sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
  			SCTP_CHUNK(chunk));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3330

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3331
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
  }
  
  /*
   * Process an inbound SHUTDOWN ACK.
   *
   * From Section 9.2:
   * Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall
   * stop the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its
   * peer, and remove all record of the association.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
3344
3345
3346
3347
3348
3349
  enum sctp_disposition sctp_sf_do_9_2_final(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3350
3351
3352
3353
3354
3355
  {
  	struct sctp_chunk *chunk = arg;
  	struct sctp_chunk *reply;
  	struct sctp_ulpevent *ev;
  
  	if (!sctp_vtag_verify(chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3356
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3357
3358
  
  	/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
922dbc5be   Xin Long   sctp: remove the ...
3359
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3360
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3361
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3362
3363
3364
3365
3366
3367
  	/* 10.2 H) SHUTDOWN COMPLETE notification
  	 *
  	 * When SCTP completes the shutdown procedures (section 9.2) this
  	 * notification is passed to the upper layer.
  	 */
  	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
a5a35e767   Vlad Yasevich   [SCTP]: Implement...
3368
  					     0, 0, 0, NULL, GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3369
3370
  	if (!ev)
  		goto nomem;
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
3371
3372
3373
3374
3375
3376
3377
3378
  	/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
  	reply = sctp_make_shutdown_complete(asoc, chunk);
  	if (!reply)
  		goto nomem_chunk;
  
  	/* Do all the commands now (after allocation), so that we
  	 * have consistent state if memory allocation failes
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
  
  	/* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall
  	 * stop the T2-shutdown timer,
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3389
3390
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_CLOSED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
3391
3392
  	SCTP_INC_STATS(net, SCTP_MIB_SHUTDOWNS);
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3393
3394
3395
3396
3397
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  
  	/* ...and remove all record of the association. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
  	return SCTP_DISPOSITION_DELETE_TCB;
df7deeb54   Vladislav Yasevich   [SCTP]: Cleanup n...
3398
3399
  nomem_chunk:
  	sctp_ulpevent_free(ev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3400
3401
3402
3403
3404
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
047a2428a   Jerome Forissier   [SCTP] Implement ...
3405
3406
   * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3407
3408
3409
3410
3411
   * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
   *    respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
   *    When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
   *    packet must fill in the Verification Tag field of the outbound
   *    packet with the Verification Tag received in the SHUTDOWN ACK and
047a2428a   Jerome Forissier   [SCTP] Implement ...
3412
3413
   *    set the T-bit in the Chunk Flags to indicate that the Verification
   *    Tag is reflected.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3414
3415
3416
3417
3418
   *
   * 8) The receiver should respond to the sender of the OOTB packet with
   *    an ABORT.  When sending the ABORT, the receiver of the OOTB packet
   *    MUST fill in the Verification Tag field of the outbound packet
   *    with the value found in the Verification Tag field of the OOTB
047a2428a   Jerome Forissier   [SCTP] Implement ...
3419
3420
3421
3422
   *    packet and set the T-bit in the Chunk Flags to indicate that the
   *    Verification Tag is reflected.  After sending this ABORT, the
   *    receiver of the OOTB packet shall discard the OOTB packet and take
   *    no further action.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3423
   */
172a1599b   Xin Long   sctp: remove the ...
3424
3425
3426
3427
3428
  enum sctp_disposition sctp_sf_ootb(struct net *net,
  				   const struct sctp_endpoint *ep,
  				   const struct sctp_association *asoc,
  				   const union sctp_subtype type,
  				   void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3429
3430
3431
  {
  	struct sctp_chunk *chunk = arg;
  	struct sk_buff *skb = chunk->skb;
922dbc5be   Xin Long   sctp: remove the ...
3432
  	struct sctp_chunkhdr *ch;
d8238d9da   Xin Long   sctp: remove the ...
3433
  	struct sctp_errhdr *err;
85c5ed4e4   Shan Wei   sctp: handle ootb...
3434
  	int ootb_cookie_ack = 0;
172a1599b   Xin Long   sctp: remove the ...
3435
3436
  	int ootb_shut_ack = 0;
  	__u8 *ch_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3437

b01a24078   Eric W. Biederman   sctp: Make the mi...
3438
  	SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3439

922dbc5be   Xin Long   sctp: remove the ...
3440
  	ch = (struct sctp_chunkhdr *)chunk->chunk_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3441
  	do {
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
3442
  		/* Report violation if the chunk is less then minimal */
922dbc5be   Xin Long   sctp: remove the ...
3443
  		if (ntohs(ch->length) < sizeof(*ch))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3444
  			return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
3445
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3446

bf911e985   Marcelo Ricardo Leitner   sctp: validate ch...
3447
3448
3449
3450
3451
  		/* Report violation if chunk len overflows */
  		ch_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length));
  		if (ch_end > skb_tail_pointer(skb))
  			return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
  						  commands);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
3452
3453
3454
  		/* Now that we know we at least have a chunk header,
  		 * do things that are type appropriate.
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3455
3456
3457
3458
3459
3460
3461
3462
3463
  		if (SCTP_CID_SHUTDOWN_ACK == ch->type)
  			ootb_shut_ack = 1;
  
  		/* RFC 2960, Section 3.3.7
  		 *   Moreover, under any circumstances, an endpoint that
  		 *   receives an ABORT  MUST NOT respond to that ABORT by
  		 *   sending an ABORT of its own.
  		 */
  		if (SCTP_CID_ABORT == ch->type)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3464
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3465

85c5ed4e4   Shan Wei   sctp: handle ootb...
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
  		/* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
  		 * or a COOKIE ACK the SCTP Packet should be silently
  		 * discarded.
  		 */
  
  		if (SCTP_CID_COOKIE_ACK == ch->type)
  			ootb_cookie_ack = 1;
  
  		if (SCTP_CID_ERROR == ch->type) {
  			sctp_walk_errors(err, ch) {
  				if (SCTP_ERROR_STALE_COOKIE == err->cause) {
  					ootb_cookie_ack = 1;
  					break;
  				}
  			}
  		}
922dbc5be   Xin Long   sctp: remove the ...
3482
  		ch = (struct sctp_chunkhdr *)ch_end;
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
3483
  	} while (ch_end < skb_tail_pointer(skb));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3484
3485
  
  	if (ootb_shut_ack)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3486
  		return sctp_sf_shut_8_4_5(net, ep, asoc, type, arg, commands);
85c5ed4e4   Shan Wei   sctp: handle ootb...
3487
  	else if (ootb_cookie_ack)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3488
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3489
  	else
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3490
  		return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3491
3492
3493
3494
3495
  }
  
  /*
   * Handle an "Out of the blue" SHUTDOWN ACK.
   *
047a2428a   Jerome Forissier   [SCTP] Implement ...
3496
3497
   * Section: 8.4 5, sctpimpguide 2.41.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3498
   * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
047a2428a   Jerome Forissier   [SCTP] Implement ...
3499
3500
3501
3502
3503
3504
   *    respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
   *    When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
   *    packet must fill in the Verification Tag field of the outbound
   *    packet with the Verification Tag received in the SHUTDOWN ACK and
   *    set the T-bit in the Chunk Flags to indicate that the Verification
   *    Tag is reflected.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3505
3506
3507
3508
3509
   *
   * Inputs
   * (endpoint, asoc, type, arg, commands)
   *
   * Outputs
172a1599b   Xin Long   sctp: remove the ...
3510
   * (enum sctp_disposition)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3511
3512
3513
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
3514
3515
3516
3517
3518
3519
3520
  static enum sctp_disposition sctp_sf_shut_8_4_5(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3521
3522
3523
3524
  {
  	struct sctp_packet *packet = NULL;
  	struct sctp_chunk *chunk = arg;
  	struct sctp_chunk *shut;
2ce955035   Eric W. Biederman   sctp: Make the ct...
3525
  	packet = sctp_ootb_pkt_new(net, asoc, chunk);
1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3526
3527
  	if (!packet)
  		return SCTP_DISPOSITION_NOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3528

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3529
3530
3531
3532
3533
3534
3535
3536
  	/* Make an SHUTDOWN_COMPLETE.
  	 * The T bit will be set if the asoc is NULL.
  	 */
  	shut = sctp_make_shutdown_complete(asoc, chunk);
  	if (!shut) {
  		sctp_ootb_pkt_free(packet);
  		return SCTP_DISPOSITION_NOMEM;
  	}
047a2428a   Jerome Forissier   [SCTP] Implement ...
3537

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3538
3539
3540
  	/* Reflect vtag if T-Bit is set */
  	if (sctp_test_T_bit(shut))
  		packet->vtag = ntohl(chunk->sctp_hdr->vtag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3541

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3542
3543
  	/* Set the skb to the belonging sock for accounting.  */
  	shut->skb->sk = ep->base.sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3544

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3545
  	sctp_packet_append_chunk(packet, shut);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3546

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3547
3548
  	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  			SCTP_PACKET(packet));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3549

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3550
  	SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3551

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3552
3553
3554
  	/* If the chunk length is invalid, we don't want to process
  	 * the reset of the packet.
  	 */
922dbc5be   Xin Long   sctp: remove the ...
3555
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3556
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3557

1ff015616   Marcelo Ricardo Leitner   sctp: reduce inde...
3558
3559
3560
3561
3562
  	/* We need to discard the rest of the packet to prevent
  	 * potential bomming attacks from additional bundled chunks.
  	 * This is documented in SCTP Threats ID.
  	 */
  	return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
  }
  
  /*
   * Handle SHUTDOWN ACK in COOKIE_ECHOED or COOKIE_WAIT state.
   *
   * Verification Tag:  8.5.1 E) Rules for packet carrying a SHUTDOWN ACK
   *   If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the
   *   procedures in section 8.4 SHOULD be followed, in other words it
   *   should be treated as an Out Of The Blue packet.
   *   [This means that we do NOT check the Verification Tag on these
   *   chunks. --piggy ]
   *
   */
172a1599b   Xin Long   sctp: remove the ...
3576
3577
3578
3579
3580
3581
  enum sctp_disposition sctp_sf_do_8_5_1_E_sa(struct net *net,
  					    const struct sctp_endpoint *ep,
  					    const struct sctp_association *asoc,
  					    const union sctp_subtype type,
  					    void *arg,
  					    struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3582
  {
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
3583
3584
3585
  	struct sctp_chunk *chunk = arg;
  
  	/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
922dbc5be   Xin Long   sctp: remove the ...
3586
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3587
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
3588
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3589
3590
3591
3592
3593
  	/* Although we do have an association in this case, it corresponds
  	 * to a restarted association. So the packet is treated as an OOTB
  	 * packet and the state function that handles OOTB SHUTDOWN_ACK is
  	 * called with a NULL association.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3594
  	SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);
8190f89df   Wei Yongjun   sctp: Fix the SNM...
3595

24cb81a6a   Eric W. Biederman   sctp: Push struct...
3596
  	return sctp_sf_shut_8_4_5(net, ep, NULL, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3597
3598
3599
  }
  
  /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.  */
172a1599b   Xin Long   sctp: remove the ...
3600
3601
3602
3603
3604
3605
  enum sctp_disposition sctp_sf_do_asconf(struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3606
  {
172a1599b   Xin Long   sctp: remove the ...
3607
3608
3609
3610
3611
  	struct sctp_paramhdr *err_param = NULL;
  	struct sctp_chunk *asconf_ack = NULL;
  	struct sctp_chunk *chunk = arg;
  	struct sctp_addiphdr *hdr;
  	__u32 serial;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3612
3613
3614
3615
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3616
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3617
  	}
6afd2e83c   Vlad Yasevich   [SCTP]: Discard u...
3618
3619
3620
3621
3622
3623
  	/* ADD-IP: Section 4.1.1
  	 * This chunk MUST be sent in an authenticated way by using
  	 * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk
  	 * is received unauthenticated it MUST be silently discarded as
  	 * described in [I-D.ietf-tsvwg-sctp-auth].
  	 */
a2eeacc83   Xin Long   sctp: check asoc ...
3624
3625
  	if (!asoc->peer.asconf_capable ||
  	    (!net->sctp.addip_noauth && !chunk->auth))
68d754694   Xin Long   sctp: remove the ...
3626
3627
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
  					     commands);
6afd2e83c   Vlad Yasevich   [SCTP]: Discard u...
3628

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3629
  	/* Make sure that the ASCONF ADDIP chunk has a valid length.  */
68d754694   Xin Long   sctp: remove the ...
3630
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_addip_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3631
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3632
  						  commands);
65205cc46   Xin Long   sctp: remove the ...
3633
  	hdr = (struct sctp_addiphdr *)chunk->skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3634
  	serial = ntohl(hdr->serial);
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
3635
  	/* Verify the ASCONF chunk before processing it. */
9de7922bc   Daniel Borkmann   net: sctp: fix sk...
3636
  	if (!sctp_verify_asconf(asoc, chunk, true, &err_param))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3637
  		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
ba0166708   Wei Yongjun   sctp: Fix kernel ...
3638
  						  (void *)err_param, commands);
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
3639

a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3640
  	/* ADDIP 5.2 E1) Compare the value of the serial number to the value
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3641
  	 * the endpoint stored in a new association variable
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3642
  	 * 'Peer-Serial-Number'.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3643
3644
  	 */
  	if (serial == asoc->peer.addip_serial + 1) {
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
  		/* If this is the first instance of ASCONF in the packet,
  		 * we can clean our old ASCONF-ACKs.
  		 */
  		if (!chunk->has_asconf)
  			sctp_assoc_clean_asconf_ack_cache(asoc);
  
  		/* ADDIP 5.2 E4) When the Sequence Number matches the next one
  		 * expected, process the ASCONF as described below and after
  		 * processing the ASCONF Chunk, append an ASCONF-ACK Chunk to
  		 * the response packet and cache a copy of it (in the event it
  		 * later needs to be retransmitted).
  		 *
  		 * Essentially, do V1-V5.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3658
3659
3660
3661
3662
  		 */
  		asconf_ack = sctp_process_asconf((struct sctp_association *)
  						 asoc, chunk);
  		if (!asconf_ack)
  			return SCTP_DISPOSITION_NOMEM;
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
  	} else if (serial < asoc->peer.addip_serial + 1) {
  		/* ADDIP 5.2 E2)
  		 * If the value found in the Sequence Number is less than the
  		 * ('Peer- Sequence-Number' + 1), simply skip to the next
  		 * ASCONF, and include in the outbound response packet
  		 * any previously cached ASCONF-ACK response that was
  		 * sent and saved that matches the Sequence Number of the
  		 * ASCONF.  Note: It is possible that no cached ASCONF-ACK
  		 * Chunk exists.  This will occur when an older ASCONF
  		 * arrives out of order.  In such a case, the receiver
  		 * should skip the ASCONF Chunk and not include ASCONF-ACK
  		 * Chunk for that chunk.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3675
  		 */
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3676
3677
  		asconf_ack = sctp_assoc_lookup_asconf_ack(asoc, hdr->serial);
  		if (!asconf_ack)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3678
  			return SCTP_DISPOSITION_DISCARD;
31b02e154   Vlad Yasevich   sctp: Failover tr...
3679
3680
3681
3682
3683
3684
  
  		/* Reset the transport so that we select the correct one
  		 * this time around.  This is to make sure that we don't
  		 * accidentally use a stale transport that's been removed.
  		 */
  		asconf_ack->transport = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3685
  	} else {
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3686
  		/* ADDIP 5.2 E5) Otherwise, the ASCONF Chunk is discarded since
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3687
  		 * it must be either a stale packet or from an attacker.
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3688
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3689
3690
  		return SCTP_DISPOSITION_DISCARD;
  	}
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3691
3692
3693
3694
3695
3696
3697
  	/* ADDIP 5.2 E6)  The destination address of the SCTP packet
  	 * containing the ASCONF-ACK Chunks MUST be the source address of
  	 * the SCTP packet that held the ASCONF Chunks.
  	 *
  	 * To do this properly, we'll set the destination address of the chunk
  	 * and at the transmit time, will try look up the transport to use.
  	 * Since ASCONFs may be bundled, the correct transport may not be
94e2bd688   Thadeu Lima de Souza Cascardo   tree-wide: fix so...
3698
  	 * created until we process the entire packet, thus this workaround.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3699
  	 */
a08de64d0   Vlad Yasevich   [SCTP]: Update AS...
3700
  	asconf_ack->dest = chunk->source;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3701
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
6af29ccc2   Michio Honda   sctp: Bundle HEAE...
3702
  	if (asoc->new_transport) {
f7010e614   wangweidong   sctp: fix checkpa...
3703
  		sctp_sf_heartbeat(ep, asoc, type, asoc->new_transport, commands);
6af29ccc2   Michio Honda   sctp: Bundle HEAE...
3704
3705
  		((struct sctp_association *)asoc)->new_transport = NULL;
  	}
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3706

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3707
3708
  	return SCTP_DISPOSITION_CONSUME;
  }
fbd019737   Xin Long   sctp: avoid runni...
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
  static enum sctp_disposition sctp_send_next_asconf(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					struct sctp_association *asoc,
  					const union sctp_subtype type,
  					struct sctp_cmd_seq *commands)
  {
  	struct sctp_chunk *asconf;
  	struct list_head *entry;
  
  	if (list_empty(&asoc->addip_chunk_list))
  		return SCTP_DISPOSITION_CONSUME;
  
  	entry = asoc->addip_chunk_list.next;
  	asconf = list_entry(entry, struct sctp_chunk, list);
  
  	list_del_init(entry);
  	sctp_chunk_hold(asconf);
  	asoc->addip_last_asconf = asconf;
  
  	return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3731
3732
3733
3734
3735
  /*
   * ADDIP Section 4.3 General rules for address manipulation
   * When building TLV parameters for the ASCONF Chunk that will add or
   * delete IP addresses the D0 to D13 rules should be applied:
   */
172a1599b   Xin Long   sctp: remove the ...
3736
3737
3738
3739
3740
3741
  enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net,
  					    const struct sctp_endpoint *ep,
  					    const struct sctp_association *asoc,
  					    const union sctp_subtype type,
  					    void *arg,
  					    struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3742
  {
172a1599b   Xin Long   sctp: remove the ...
3743
3744
3745
3746
3747
3748
  	struct sctp_chunk *last_asconf = asoc->addip_last_asconf;
  	struct sctp_paramhdr *err_param = NULL;
  	struct sctp_chunk *asconf_ack = arg;
  	struct sctp_addiphdr *addip_hdr;
  	__u32 sent_serial, rcvd_serial;
  	struct sctp_chunk *abort;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3749
3750
3751
3752
  
  	if (!sctp_vtag_verify(asconf_ack, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3753
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3754
  	}
6afd2e83c   Vlad Yasevich   [SCTP]: Discard u...
3755
3756
3757
3758
3759
3760
  	/* ADD-IP, Section 4.1.2:
  	 * This chunk MUST be sent in an authenticated way by using
  	 * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk
  	 * is received unauthenticated it MUST be silently discarded as
  	 * described in [I-D.ietf-tsvwg-sctp-auth].
  	 */
a2eeacc83   Xin Long   sctp: check asoc ...
3761
3762
  	if (!asoc->peer.asconf_capable ||
  	    (!net->sctp.addip_noauth && !asconf_ack->auth))
68d754694   Xin Long   sctp: remove the ...
3763
3764
  		return sctp_sf_discard_chunk(net, ep, asoc, type, arg,
  					     commands);
6afd2e83c   Vlad Yasevich   [SCTP]: Discard u...
3765

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3766
  	/* Make sure that the ADDIP chunk has a valid length.  */
68d754694   Xin Long   sctp: remove the ...
3767
3768
  	if (!sctp_chunk_length_valid(asconf_ack,
  				     sizeof(struct sctp_addip_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3769
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3770
  						  commands);
65205cc46   Xin Long   sctp: remove the ...
3771
  	addip_hdr = (struct sctp_addiphdr *)asconf_ack->skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3772
  	rcvd_serial = ntohl(addip_hdr->serial);
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
3773
  	/* Verify the ASCONF-ACK chunk before processing it. */
9de7922bc   Daniel Borkmann   net: sctp: fix sk...
3774
  	if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3775
  		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
ba0166708   Wei Yongjun   sctp: Fix kernel ...
3776
  			   (void *)err_param, commands);
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
3777

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3778
  	if (last_asconf) {
65205cc46   Xin Long   sctp: remove the ...
3779
  		addip_hdr = (struct sctp_addiphdr *)last_asconf->subh.addip_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
  		sent_serial = ntohl(addip_hdr->serial);
  	} else {
  		sent_serial = asoc->addip_serial - 1;
  	}
  
  	/* D0) If an endpoint receives an ASCONF-ACK that is greater than or
  	 * equal to the next serial number to be used but no ASCONF chunk is
  	 * outstanding the endpoint MUST ABORT the association. Note that a
  	 * sequence number is greater than if it is no more than 2^^31-1
  	 * larger than the current sequence number (using serial arithmetic).
  	 */
  	if (ADDIP_SERIAL_gte(rcvd_serial, sent_serial + 1) &&
  	    !(asoc->addip_last_asconf)) {
  		abort = sctp_make_abort(asoc, asconf_ack,
d8238d9da   Xin Long   sctp: remove the ...
3794
  					sizeof(struct sctp_errhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3795
  		if (abort) {
00f1c2df2   Wei Yongjun   SCTP: Fix to enco...
3796
  			sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3797
3798
3799
3800
3801
3802
3803
3804
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(abort));
  		}
  		/* We are going to ABORT, so we might as well stop
  		 * processing the rest of the chunks in the packet.
  		 */
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
cb3f837ba   wangweidong   sctp: fix checkpa...
3805
  		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
3806
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3807
  				SCTP_ERROR(ECONNABORTED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3808
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
3809
  				SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
b01a24078   Eric W. Biederman   sctp: Make the mi...
3810
3811
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3812
3813
3814
3815
3816
3817
3818
3819
  		return SCTP_DISPOSITION_ABORT;
  	}
  
  	if ((rcvd_serial == sent_serial) && asoc->addip_last_asconf) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
  
  		if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
fbd019737   Xin Long   sctp: avoid runni...
3820
3821
3822
3823
  					     asconf_ack))
  			return sctp_send_next_asconf(net, ep,
  					(struct sctp_association *)asoc,
  							type, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3824
3825
  
  		abort = sctp_make_abort(asoc, asconf_ack,
d8238d9da   Xin Long   sctp: remove the ...
3826
  					sizeof(struct sctp_errhdr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3827
  		if (abort) {
00f1c2df2   Wei Yongjun   SCTP: Fix to enco...
3828
  			sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3829
3830
3831
3832
3833
3834
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(abort));
  		}
  		/* We are going to ABORT, so we might as well stop
  		 * processing the rest of the chunks in the packet.
  		 */
cb3f837ba   wangweidong   sctp: fix checkpa...
3835
  		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
3836
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3837
  				SCTP_ERROR(ECONNABORTED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3838
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
3839
  				SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
b01a24078   Eric W. Biederman   sctp: Make the mi...
3840
3841
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3842
3843
3844
3845
3846
  		return SCTP_DISPOSITION_ABORT;
  	}
  
  	return SCTP_DISPOSITION_DISCARD;
  }
2040d3d7a   Xin Long   sctp: add reconf ...
3847
  /* RE-CONFIG Section 5.2 Upon reception of an RECONF Chunk. */
172a1599b   Xin Long   sctp: remove the ...
3848
3849
3850
3851
3852
3853
  enum sctp_disposition sctp_sf_do_reconf(struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
2040d3d7a   Xin Long   sctp: add reconf ...
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
  {
  	struct sctp_paramhdr *err_param = NULL;
  	struct sctp_chunk *chunk = arg;
  	struct sctp_reconf_chunk *hdr;
  	union sctp_params param;
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
  	}
  
  	/* Make sure that the RECONF chunk has a valid length.  */
  	if (!sctp_chunk_length_valid(chunk, sizeof(*hdr)))
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
  						  commands);
  
  	if (!sctp_verify_reconf(asoc, chunk, &err_param))
  		return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
  						  (void *)err_param, commands);
  
  	hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
  	sctp_walk_params(param, hdr, params) {
  		struct sctp_chunk *reply = NULL;
  		struct sctp_ulpevent *ev = NULL;
  
  		if (param.p->type == SCTP_PARAM_RESET_OUT_REQUEST)
  			reply = sctp_process_strreset_outreq(
  				(struct sctp_association *)asoc, param, &ev);
  		else if (param.p->type == SCTP_PARAM_RESET_IN_REQUEST)
  			reply = sctp_process_strreset_inreq(
  				(struct sctp_association *)asoc, param, &ev);
692787cef   Xin Long   sctp: implement r...
3886
3887
3888
  		else if (param.p->type == SCTP_PARAM_RESET_TSN_REQUEST)
  			reply = sctp_process_strreset_tsnreq(
  				(struct sctp_association *)asoc, param, &ev);
50a41591f   Xin Long   sctp: implement r...
3889
3890
3891
  		else if (param.p->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS)
  			reply = sctp_process_strreset_addstrm_out(
  				(struct sctp_association *)asoc, param, &ev);
c5c4ebb3a   Xin Long   sctp: implement r...
3892
3893
3894
  		else if (param.p->type == SCTP_PARAM_RESET_ADD_IN_STREAMS)
  			reply = sctp_process_strreset_addstrm_in(
  				(struct sctp_association *)asoc, param, &ev);
11ae76e67   Xin Long   sctp: implement r...
3895
3896
3897
  		else if (param.p->type == SCTP_PARAM_RESET_RESPONSE)
  			reply = sctp_process_strreset_resp(
  				(struct sctp_association *)asoc, param, &ev);
2040d3d7a   Xin Long   sctp: add reconf ...
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
  
  		if (ev)
  			sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  					SCTP_ULPEVENT(ev));
  
  		if (reply)
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(reply));
  	}
  
  	return SCTP_DISPOSITION_CONSUME;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
  /*
   * PR-SCTP Section 3.6 Receiver Side Implementation of PR-SCTP
   *
   * When a FORWARD TSN chunk arrives, the data receiver MUST first update
   * its cumulative TSN point to the value carried in the FORWARD TSN
   * chunk, and then MUST further advance its cumulative TSN point locally
   * if possible.
   * After the above processing, the data receiver MUST stop reporting any
   * missing TSNs earlier than or equal to the new cumulative TSN point.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
3924
3925
3926
3927
3928
3929
  enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3930
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3931
  	struct sctp_fwdtsn_hdr *fwdtsn_hdr;
172a1599b   Xin Long   sctp: remove the ...
3932
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3933
3934
3935
3936
3937
3938
  	__u16 len;
  	__u32 tsn;
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3939
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3940
  	}
d15c9ede6   Xin Long   sctp: process fwd...
3941
3942
  	if (!asoc->peer.prsctp_capable)
  		return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3943
  	/* Make sure that the FORWARD_TSN chunk has valid length.  */
0fc2ea922   Xin Long   sctp: implement v...
3944
  	if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
3945
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3946
3947
3948
3949
3950
3951
3952
3953
3954
  						  commands);
  
  	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
  	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
  	len = ntohs(chunk->chunk_hdr->length);
  	len -= sizeof(struct sctp_chunkhdr);
  	skb_pull(chunk->skb, len);
  
  	tsn = ntohl(fwdtsn_hdr->new_cum_tsn);
bb33381d0   Daniel Borkmann   net: sctp: rework...
3955
3956
  	pr_debug("%s: TSN 0x%x
  ", __func__, tsn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3957
3958
3959
3960
3961
3962
  
  	/* The TSN is too high--silently discard the chunk and count on it
  	 * getting retransmitted later.
  	 */
  	if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
  		goto discard_noforce;
0fc2ea922   Xin Long   sctp: implement v...
3963
3964
  	if (!asoc->stream.si->validate_ftsn(chunk))
  		goto discard_noforce;
9fcb95a10   Wei Yongjun   sctp: Avoid memor...
3965

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3966
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
0fc2ea922   Xin Long   sctp: implement v...
3967
  	if (len > sctp_ftsnhdr_len(&asoc->stream))
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3968
  		sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3969
  				SCTP_CHUNK(chunk));
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3970

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3971
  	/* Count this as receiving DATA. */
9f70f46bd   Neil Horman   sctp: properly la...
3972
  	if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3973
3974
3975
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
  	}
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3976

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3977
  	/* FIXME: For now send a SACK, but DATA processing may
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
3978
  	 * send another.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3979
3980
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3981
3982
3983
3984
3985
3986
  
  	return SCTP_DISPOSITION_CONSUME;
  
  discard_noforce:
  	return SCTP_DISPOSITION_DISCARD;
  }
172a1599b   Xin Long   sctp: remove the ...
3987
3988
3989
3990
3991
3992
3993
  enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3994
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3995
  	struct sctp_fwdtsn_hdr *fwdtsn_hdr;
172a1599b   Xin Long   sctp: remove the ...
3996
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3997
3998
3999
4000
4001
4002
  	__u16 len;
  	__u32 tsn;
  
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4003
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4004
  	}
d15c9ede6   Xin Long   sctp: process fwd...
4005
4006
  	if (!asoc->peer.prsctp_capable)
  		return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4007
  	/* Make sure that the FORWARD_TSN chunk has a valid length.  */
0fc2ea922   Xin Long   sctp: implement v...
4008
  	if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4009
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4010
4011
4012
4013
4014
4015
4016
4017
4018
  						  commands);
  
  	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
  	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
  	len = ntohs(chunk->chunk_hdr->length);
  	len -= sizeof(struct sctp_chunkhdr);
  	skb_pull(chunk->skb, len);
  
  	tsn = ntohl(fwdtsn_hdr->new_cum_tsn);
bb33381d0   Daniel Borkmann   net: sctp: rework...
4019
4020
  	pr_debug("%s: TSN 0x%x
  ", __func__, tsn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4021
4022
4023
4024
4025
4026
  
  	/* The TSN is too high--silently discard the chunk and count on it
  	 * getting retransmitted later.
  	 */
  	if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
  		goto gen_shutdown;
0fc2ea922   Xin Long   sctp: implement v...
4027
4028
  	if (!asoc->stream.si->validate_ftsn(chunk))
  		goto gen_shutdown;
9fcb95a10   Wei Yongjun   sctp: Avoid memor...
4029

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4030
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
0fc2ea922   Xin Long   sctp: implement v...
4031
  	if (len > sctp_ftsnhdr_len(&asoc->stream))
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
4032
  		sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4033
  				SCTP_CHUNK(chunk));
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
4034

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
  	/* Go a head and force a SACK, since we are shutting down. */
  gen_shutdown:
  	/* Implementor's Guide.
  	 *
  	 * While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
  	 * respond to each received packet containing one or more DATA chunk(s)
  	 * with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SHUTDOWN, SCTP_NULL());
  	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
4047
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4048
4049
4050
  }
  
  /*
25985edce   Lucas De Marchi   Fix common misspe...
4051
   * SCTP-AUTH Section 6.3 Receiving authenticated chukns
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
   *
   *    The receiver MUST use the HMAC algorithm indicated in the HMAC
   *    Identifier field.  If this algorithm was not specified by the
   *    receiver in the HMAC-ALGO parameter in the INIT or INIT-ACK chunk
   *    during association setup, the AUTH chunk and all chunks after it MUST
   *    be discarded and an ERROR chunk SHOULD be sent with the error cause
   *    defined in Section 4.1.
   *
   *    If an endpoint with no shared key receives a Shared Key Identifier
   *    other than 0, it MUST silently discard all authenticated chunks.  If
   *    the endpoint has at least one endpoint pair shared key for the peer,
   *    it MUST use the key specified by the Shared Key Identifier if a
   *    key has been configured for that Shared Key Identifier.  If no
   *    endpoint pair shared key has been configured for that Shared Key
   *    Identifier, all authenticated chunks MUST be silently discarded.
   *
   * Verification Tag:  8.5 Verification Tag [Normal verification]
   *
   * The return value is the disposition of the chunk.
   */
4785c7ae1   Xin Long   sctp: remove the ...
4072
  static enum sctp_ierror sctp_sf_authenticate(
172a1599b   Xin Long   sctp: remove the ...
4073
  					const struct sctp_association *asoc,
172a1599b   Xin Long   sctp: remove the ...
4074
  					struct sctp_chunk *chunk)
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4075
  {
1b1e0bc99   Xin Long   sctp: add refcnt ...
4076
  	struct sctp_shared_key *sh_key = NULL;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4077
  	struct sctp_authhdr *auth_hdr;
172a1599b   Xin Long   sctp: remove the ...
4078
  	__u8 *save_digest, *digest;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4079
4080
4081
  	struct sctp_hmac *hmac;
  	unsigned int sig_len;
  	__u16 key_id;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4082
4083
4084
4085
  
  	/* Pull in the auth header, so we can do some more verification */
  	auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
  	chunk->subh.auth_hdr = auth_hdr;
bb96dec74   Xin Long   sctp: remove the ...
4086
  	skb_pull(chunk->skb, sizeof(*auth_hdr));
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4087

02582e9bc   Masanari Iida   treewide: fix typ...
4088
  	/* Make sure that we support the HMAC algorithm from the auth
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4089
4090
4091
4092
4093
4094
4095
4096
4097
  	 * chunk.
  	 */
  	if (!sctp_auth_asoc_verify_hmac_id(asoc, auth_hdr->hmac_id))
  		return SCTP_IERROR_AUTH_BAD_HMAC;
  
  	/* Make sure that the provided shared key identifier has been
  	 * configured
  	 */
  	key_id = ntohs(auth_hdr->shkey_id);
1b1e0bc99   Xin Long   sctp: add refcnt ...
4098
4099
4100
4101
4102
  	if (key_id != asoc->active_key_id) {
  		sh_key = sctp_auth_get_shkey(asoc, key_id);
  		if (!sh_key)
  			return SCTP_IERROR_AUTH_BAD_KEYID;
  	}
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4103
4104
4105
4106
  
  	/* Make sure that the length of the signature matches what
  	 * we expect.
  	 */
bb96dec74   Xin Long   sctp: remove the ...
4107
4108
  	sig_len = ntohs(chunk->chunk_hdr->length) -
  		  sizeof(struct sctp_auth_chunk);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
  	hmac = sctp_auth_get_hmac(ntohs(auth_hdr->hmac_id));
  	if (sig_len != hmac->hmac_len)
  		return SCTP_IERROR_PROTO_VIOLATION;
  
  	/* Now that we've done validation checks, we can compute and
  	 * verify the hmac.  The steps involved are:
  	 *  1. Save the digest from the chunk.
  	 *  2. Zero out the digest in the chunk.
  	 *  3. Compute the new digest
  	 *  4. Compare saved and new digests.
  	 */
  	digest = auth_hdr->hmac;
  	skb_pull(chunk->skb, sig_len);
  
  	save_digest = kmemdup(digest, sig_len, GFP_ATOMIC);
  	if (!save_digest)
  		goto nomem;
  
  	memset(digest, 0, sig_len);
  
  	sctp_auth_calculate_hmac(asoc, chunk->skb,
bb96dec74   Xin Long   sctp: remove the ...
4130
  				 (struct sctp_auth_chunk *)chunk->chunk_hdr,
1b1e0bc99   Xin Long   sctp: add refcnt ...
4131
  				 sh_key, GFP_ATOMIC);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
  
  	/* Discard the packet if the digests do not match */
  	if (memcmp(save_digest, digest, sig_len)) {
  		kfree(save_digest);
  		return SCTP_IERROR_BAD_SIG;
  	}
  
  	kfree(save_digest);
  	chunk->auth = 1;
  
  	return SCTP_IERROR_NO_ERROR;
  nomem:
  	return SCTP_IERROR_NOMEM;
  }
172a1599b   Xin Long   sctp: remove the ...
4146
4147
4148
4149
4150
  enum sctp_disposition sctp_sf_eat_auth(struct net *net,
  				       const struct sctp_endpoint *ep,
  				       const struct sctp_association *asoc,
  				       const union sctp_subtype type,
  				       void *arg, struct sctp_cmd_seq *commands)
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4151
  {
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4152
  	struct sctp_chunk *chunk = arg;
4785c7ae1   Xin Long   sctp: remove the ...
4153
  	struct sctp_authhdr *auth_hdr;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4154
  	struct sctp_chunk *err_chunk;
4785c7ae1   Xin Long   sctp: remove the ...
4155
  	enum sctp_ierror error;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4156

d2f19fa13   Wei Yongjun   [SCTP]: Fix kerne...
4157
4158
  	/* Make sure that the peer has AUTH capable */
  	if (!asoc->peer.auth_capable)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4159
  		return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
d2f19fa13   Wei Yongjun   [SCTP]: Fix kerne...
4160

bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4161
4162
4163
  	if (!sctp_vtag_verify(chunk, asoc)) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
  				SCTP_NULL());
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4164
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4165
4166
4167
4168
  	}
  
  	/* Make sure that the AUTH chunk has valid length.  */
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_auth_chunk)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4169
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4170
4171
4172
  						  commands);
  
  	auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
59d8d4434   Xin Long   sctp: delay the a...
4173
  	error = sctp_sf_authenticate(asoc, chunk);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4174
  	switch (error) {
7fd71b1e0   Joe Perches   sctp: Reduce swit...
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
  	case SCTP_IERROR_AUTH_BAD_HMAC:
  		/* Generate the ERROR chunk and discard the rest
  		 * of the packet
  		 */
  		err_chunk = sctp_make_op_error(asoc, chunk,
  					       SCTP_ERROR_UNSUP_HMAC,
  					       &auth_hdr->hmac_id,
  					       sizeof(__u16), 0);
  		if (err_chunk) {
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err_chunk));
  		}
df561f668   Gustavo A. R. Silva   treewide: Use fal...
4187
  		fallthrough;
7fd71b1e0   Joe Perches   sctp: Reduce swit...
4188
4189
  	case SCTP_IERROR_AUTH_BAD_KEYID:
  	case SCTP_IERROR_BAD_SIG:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4190
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
7fd71b1e0   Joe Perches   sctp: Reduce swit...
4191
4192
  
  	case SCTP_IERROR_PROTO_VIOLATION:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4193
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
7fd71b1e0   Joe Perches   sctp: Reduce swit...
4194
4195
4196
4197
4198
4199
4200
  						  commands);
  
  	case SCTP_IERROR_NOMEM:
  		return SCTP_DISPOSITION_NOMEM;
  
  	default:			/* Prevent gcc warnings */
  		break;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4201
  	}
65b07e5d0   Vlad Yasevich   [SCTP]: API updat...
4202
4203
4204
4205
  	if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) {
  		struct sctp_ulpevent *ev;
  
  		ev = sctp_ulpevent_make_authkey(asoc, ntohs(auth_hdr->shkey_id),
ec2e506c6   Xin Long   sctp: add SCTP_AU...
4206
  				    SCTP_AUTH_NEW_KEY, GFP_ATOMIC);
65b07e5d0   Vlad Yasevich   [SCTP]: API updat...
4207
4208
4209
4210
4211
4212
4213
  
  		if (!ev)
  			return -ENOMEM;
  
  		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
  				SCTP_ULPEVENT(ev));
  	}
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4214
4215
4216
4217
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
   * Process an unknown chunk.
   *
   * Section: 3.2. Also, 2.1 in the implementor's guide.
   *
   * Chunk Types are encoded such that the highest-order two bits specify
   * the action that must be taken if the processing endpoint does not
   * recognize the Chunk Type.
   *
   * 00 - Stop processing this SCTP packet and discard it, do not process
   *      any further chunks within it.
   *
   * 01 - Stop processing this SCTP packet and discard it, do not process
   *      any further chunks within it, and report the unrecognized
   *      chunk in an 'Unrecognized Chunk Type'.
   *
   * 10 - Skip this chunk and continue processing.
   *
   * 11 - Skip this chunk and continue processing, but report in an ERROR
   *      Chunk using the 'Unrecognized Chunk Type' cause of error.
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
4240
4241
4242
4243
4244
4245
  enum sctp_disposition sctp_sf_unk_chunk(struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4246
4247
4248
  {
  	struct sctp_chunk *unk_chunk = arg;
  	struct sctp_chunk *err_chunk;
922dbc5be   Xin Long   sctp: remove the ...
4249
  	struct sctp_chunkhdr *hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4250

bb33381d0   Daniel Borkmann   net: sctp: rework...
4251
4252
  	pr_debug("%s: processing unknown chunk id:%d
  ", __func__, type.chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4253
4254
  
  	if (!sctp_vtag_verify(unk_chunk, asoc))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4255
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4256
4257
4258
4259
4260
  
  	/* Make sure that the chunk has a valid length.
  	 * Since we don't know the chunk type, we use a general
  	 * chunkhdr structure to make a comparison.
  	 */
922dbc5be   Xin Long   sctp: remove the ...
4261
  	if (!sctp_chunk_length_valid(unk_chunk, sizeof(*hdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4262
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4263
4264
4265
4266
4267
  						  commands);
  
  	switch (type.chunk & SCTP_CID_ACTION_MASK) {
  	case SCTP_CID_ACTION_DISCARD:
  		/* Discard the packet.  */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4268
  		return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4269
  	case SCTP_CID_ACTION_DISCARD_ERR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4270
4271
4272
4273
  		/* Generate an ERROR chunk as response. */
  		hdr = unk_chunk->chunk_hdr;
  		err_chunk = sctp_make_op_error(asoc, unk_chunk,
  					       SCTP_ERROR_UNKNOWN_CHUNK, hdr,
e2f036a97   Marcelo Ricardo Leitner   sctp: rename WORD...
4274
  					       SCTP_PAD4(ntohs(hdr->length)),
6383cfb3e   Vlad Yasevich   sctp: Fix malform...
4275
  					       0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4276
4277
4278
4279
  		if (err_chunk) {
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err_chunk));
  		}
2e3216cd5   Vlad Yasevich   sctp: Follow secu...
4280
4281
  
  		/* Discard the packet.  */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4282
  		sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4283
  		return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4284
4285
4286
  	case SCTP_CID_ACTION_SKIP:
  		/* Skip the chunk.  */
  		return SCTP_DISPOSITION_DISCARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4287
4288
4289
4290
4291
  	case SCTP_CID_ACTION_SKIP_ERR:
  		/* Generate an ERROR chunk as response. */
  		hdr = unk_chunk->chunk_hdr;
  		err_chunk = sctp_make_op_error(asoc, unk_chunk,
  					       SCTP_ERROR_UNKNOWN_CHUNK, hdr,
e2f036a97   Marcelo Ricardo Leitner   sctp: rename WORD...
4292
  					       SCTP_PAD4(ntohs(hdr->length)),
6383cfb3e   Vlad Yasevich   sctp: Fix malform...
4293
  					       0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4294
4295
4296
4297
4298
4299
  		if (err_chunk) {
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err_chunk));
  		}
  		/* Skip the chunk.  */
  		return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
  	default:
  		break;
  	}
  
  	return SCTP_DISPOSITION_DISCARD;
  }
  
  /*
   * Discard the chunk.
   *
   * Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
   * [Too numerous to mention...]
   * Verification Tag: No verification needed.
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
4321
4322
4323
4324
4325
4326
  enum sctp_disposition sctp_sf_discard_chunk(struct net *net,
  					    const struct sctp_endpoint *ep,
  					    const struct sctp_association *asoc,
  					    const union sctp_subtype type,
  					    void *arg,
  					    struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4327
  {
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4328
4329
4330
4331
4332
4333
  	struct sctp_chunk *chunk = arg;
  
  	/* Make sure that the chunk has a valid length.
  	 * Since we don't know the chunk type, we use a general
  	 * chunkhdr structure to make a comparison.
  	 */
922dbc5be   Xin Long   sctp: remove the ...
4334
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4335
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4336
  						  commands);
bb33381d0   Daniel Borkmann   net: sctp: rework...
4337
4338
  	pr_debug("%s: chunk:%d is discarded
  ", __func__, type.chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
  	return SCTP_DISPOSITION_DISCARD;
  }
  
  /*
   * Discard the whole packet.
   *
   * Section: 8.4 2)
   *
   * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
   *    silently discard the OOTB packet and take no further action.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
   *
   * Verification Tag: No verification necessary
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
4360
4361
4362
4363
4364
  enum sctp_disposition sctp_sf_pdiscard(struct net *net,
  				       const struct sctp_endpoint *ep,
  				       const struct sctp_association *asoc,
  				       const union sctp_subtype type,
  				       void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4365
  {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4366
  	SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_DISCARDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
  	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  
  /*
   * The other end is violating protocol.
   *
   * Section: Not specified
   * Verification Tag: Not specified
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (asoc, reply_msg, msg_up, timers, counters)
   *
   * We simply tag the chunk as a violation.  The state machine will log
   * the violation and continue.
   */
172a1599b   Xin Long   sctp: remove the ...
4387
4388
4389
4390
4391
4392
  enum sctp_disposition sctp_sf_violation(struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4393
  {
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4394
4395
4396
  	struct sctp_chunk *chunk = arg;
  
  	/* Make sure that the chunk has a valid length. */
922dbc5be   Xin Long   sctp: remove the ...
4397
  	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4398
  		return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4399
  						  commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4400
4401
  	return SCTP_DISPOSITION_VIOLATION;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4402
  /*
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4403
   * Common function to handle a protocol violation.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4404
   */
172a1599b   Xin Long   sctp: remove the ...
4405
4406
4407
4408
4409
4410
4411
4412
  static enum sctp_disposition sctp_sf_abort_violation(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					void *arg,
  					struct sctp_cmd_seq *commands,
  					const __u8 *payload,
  					const size_t paylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4413
  {
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4414
  	struct sctp_packet *packet = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4415
4416
  	struct sctp_chunk *chunk =  arg;
  	struct sctp_chunk *abort = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4417

bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4418
4419
4420
4421
4422
4423
4424
4425
  	/* SCTP-AUTH, Section 6.3:
  	 *    It should be noted that if the receiver wants to tear
  	 *    down an association in an authenticated way only, the
  	 *    handling of malformed packets should not result in
  	 *    tearing down the association.
  	 *
  	 * This means that if we only want to abort associations
  	 * in an authenticated way (i.e AUTH+ABORT), then we
25985edce   Lucas De Marchi   Fix common misspe...
4426
  	 * can't destroy this association just because the packet
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
4427
4428
4429
4430
  	 * was malformed.
  	 */
  	if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
  		goto discard;
9abed245a   Jesper Juhl   Fix memory leak i...
4431
4432
4433
4434
  	/* Make the abort chunk. */
  	abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
  	if (!abort)
  		goto nomem;
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4435
  	if (asoc) {
f4ad85ca3   Gui Jianfeng   [SCTP]: Fix proto...
4436
4437
4438
  		/* Treat INIT-ACK as a special case during COOKIE-WAIT. */
  		if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
  		    !asoc->peer.i.init_tag) {
cb1844c47   Xin Long   sctp: remove the ...
4439
  			struct sctp_initack_chunk *initack;
f4ad85ca3   Gui Jianfeng   [SCTP]: Fix proto...
4440

cb1844c47   Xin Long   sctp: remove the ...
4441
4442
  			initack = (struct sctp_initack_chunk *)chunk->chunk_hdr;
  			if (!sctp_chunk_length_valid(chunk, sizeof(*initack)))
f4ad85ca3   Gui Jianfeng   [SCTP]: Fix proto...
4443
4444
4445
4446
4447
4448
4449
4450
4451
  				abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
  			else {
  				unsigned int inittag;
  
  				inittag = ntohl(initack->init_hdr.init_tag);
  				sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
  						SCTP_U32(inittag));
  			}
  		}
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4452
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4453
  		SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4454

ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
  		if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
  			sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  					SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  			sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  					SCTP_ERROR(ECONNREFUSED));
  			sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
  					SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
  		} else {
  			sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  					SCTP_ERROR(ECONNABORTED));
  			sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
  					SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4467
  			SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4468
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4469
  	} else {
2ce955035   Eric W. Biederman   sctp: Make the ct...
4470
  		packet = sctp_ootb_pkt_new(net, asoc, chunk);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
  
  		if (!packet)
  			goto nomem_pkt;
  
  		if (sctp_test_T_bit(abort))
  			packet->vtag = ntohl(chunk->sctp_hdr->vtag);
  
  		abort->skb->sk = ep->base.sk;
  
  		sctp_packet_append_chunk(packet, abort);
  
  		sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  			SCTP_PACKET(packet));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4484
  		SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4485
  	}
b01a24078   Eric W. Biederman   sctp: Make the mi...
4486
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
4487

56eb82bb8   Vlad Yasevich   sctp: Fix SNMP nu...
4488
  discard:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4489
  	sctp_sf_pdiscard(net, ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4490
  	return SCTP_DISPOSITION_ABORT;
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4491
4492
  nomem_pkt:
  	sctp_chunk_free(abort);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4493
4494
4495
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4496
4497
  /*
   * Handle a protocol violation when the chunk length is invalid.
025dfdafe   Frederik Schwarzer   trivial: fix then...
4498
   * "Invalid" length is identified as smaller than the minimal length a
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4499
   * given chunk can be.  For example, a SACK chunk has invalid length
d4d6c6148   Xin Long   sctp: remove the ...
4500
   * if its length is set to be smaller than the size of struct sctp_sack_chunk.
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
   *
   * We inform the other end by sending an ABORT with a Protocol Violation
   * error code.
   *
   * Section: Not specified
   * Verification Tag:  Nothing to do
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * Outputs
   * (reply_msg, msg_up, counters)
   *
   * Generate an  ABORT chunk and terminate the association.
   */
172a1599b   Xin Long   sctp: remove the ...
4515
4516
4517
4518
4519
4520
4521
  static enum sctp_disposition sctp_sf_violation_chunklen(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4522
  {
cb3f837ba   wangweidong   sctp: fix checkpa...
4523
  	static const char err_str[] = "The following chunk had invalid length:";
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4524

24cb81a6a   Eric W. Biederman   sctp: Push struct...
4525
  	return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
172a1599b   Xin Long   sctp: remove the ...
4526
  				       sizeof(err_str));
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4527
  }
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
4528
4529
  /*
   * Handle a protocol violation when the parameter length is invalid.
33c7cfdbb   Shan Wei   sctp: fix the com...
4530
4531
4532
   * If the length is smaller than the minimum length of a given parameter,
   * or accumulated length in multi parameters exceeds the end of the chunk,
   * the length is considered as invalid.
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
4533
   */
172a1599b   Xin Long   sctp: remove the ...
4534
4535
4536
4537
4538
4539
4540
  static enum sctp_disposition sctp_sf_violation_paramlen(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg, void *ext,
  					struct sctp_cmd_seq *commands)
ba0166708   Wei Yongjun   sctp: Fix kernel ...
4541
  {
ba0166708   Wei Yongjun   sctp: Fix kernel ...
4542
4543
  	struct sctp_paramhdr *param = ext;
  	struct sctp_chunk *abort = NULL;
172a1599b   Xin Long   sctp: remove the ...
4544
  	struct sctp_chunk *chunk = arg;
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
4545

ba0166708   Wei Yongjun   sctp: Fix kernel ...
4546
4547
4548
4549
4550
4551
4552
4553
4554
  	if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
  		goto discard;
  
  	/* Make the abort chunk. */
  	abort = sctp_make_violation_paramlen(asoc, chunk, param);
  	if (!abort)
  		goto nomem;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4555
  	SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
ba0166708   Wei Yongjun   sctp: Fix kernel ...
4556
4557
4558
4559
4560
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  			SCTP_ERROR(ECONNABORTED));
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
  			SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4561
4562
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
ba0166708   Wei Yongjun   sctp: Fix kernel ...
4563
4564
  
  discard:
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4565
  	sctp_sf_pdiscard(net, ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
ba0166708   Wei Yongjun   sctp: Fix kernel ...
4566
4567
4568
  	return SCTP_DISPOSITION_ABORT;
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
6f4c618dd   Wei Yongjun   SCTP : Add paramt...
4569
  }
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4570
4571
4572
4573
4574
4575
  /* Handle a protocol violation when the peer trying to advance the
   * cumulative tsn ack to a point beyond the max tsn currently sent.
   *
   * We inform the other end by sending an ABORT with a Protocol Violation
   * error code.
   */
172a1599b   Xin Long   sctp: remove the ...
4576
4577
4578
4579
4580
4581
4582
  static enum sctp_disposition sctp_sf_violation_ctsn(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4583
  {
cb3f837ba   wangweidong   sctp: fix checkpa...
4584
  	static const char err_str[] = "The cumulative tsn ack beyond the max tsn currently sent:";
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4585

24cb81a6a   Eric W. Biederman   sctp: Push struct...
4586
  	return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
172a1599b   Xin Long   sctp: remove the ...
4587
  				       sizeof(err_str));
aecedeab6   Wei Yongjun   SCTP: drop SACK i...
4588
  }
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4589
  /* Handle protocol violation of an invalid chunk bundling.  For example,
25985edce   Lucas De Marchi   Fix common misspe...
4590
   * when we have an association and we receive bundled INIT-ACK, or
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4591
   * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle"
25985edce   Lucas De Marchi   Fix common misspe...
4592
   * statement from the specs.  Additionally, there might be an attacker
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4593
4594
   * on the path and we may not want to continue this communication.
   */
172a1599b   Xin Long   sctp: remove the ...
4595
4596
4597
4598
4599
4600
4601
  static enum sctp_disposition sctp_sf_violation_chunk(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4602
  {
cb3f837ba   wangweidong   sctp: fix checkpa...
4603
  	static const char err_str[] = "The following chunk violates protocol:";
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4604
4605
  
  	if (!asoc)
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4606
  		return sctp_sf_violation(net, ep, asoc, type, arg, commands);
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4607

24cb81a6a   Eric W. Biederman   sctp: Push struct...
4608
  	return sctp_sf_abort_violation(net, ep, asoc, arg, commands, err_str,
172a1599b   Xin Long   sctp: remove the ...
4609
  				       sizeof(err_str));
ece25dfa0   Vlad Yasevich   SCTP: Clean up OO...
4610
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
  /***************************************************************************
   * These are the state functions for handling primitive (Section 10) events.
   ***************************************************************************/
  /*
   * sctp_sf_do_prm_asoc
   *
   * Section: 10.1 ULP-to-SCTP
   * B) Associate
   *
   * Format: ASSOCIATE(local SCTP instance name, destination transport addr,
   * outbound stream count)
   * -> association id [,destination transport addr list] [,outbound stream
   * count]
   *
   * This primitive allows the upper layer to initiate an association to a
   * specific peer endpoint.
   *
   * The peer endpoint shall be specified by one of the transport addresses
   * which defines the endpoint (see Section 1.4).  If the local SCTP
   * instance has not been initialized, the ASSOCIATE is considered an
   * error.
   * [This is not relevant for the kernel implementation since we do all
   * initialization at boot time.  It we hadn't initialized we wouldn't
   * get anywhere near this code.]
   *
   * An association id, which is a local handle to the SCTP association,
   * will be returned on successful establishment of the association. If
   * SCTP is not able to open an SCTP association with the peer endpoint,
   * an error is returned.
   * [In the kernel implementation, the struct sctp_association needs to
   * be created BEFORE causing this primitive to run.]
   *
   * Other association parameters may be returned, including the
   * complete destination transport addresses of the peer as well as the
   * outbound stream count of the local endpoint. One of the transport
   * address from the returned destination addresses will be selected by
   * the local endpoint as default primary path for sending SCTP packets
   * to this peer.  The returned "destination transport addr list" can
   * be used by the ULP to change the default primary path or to force
   * sending a packet to a specific transport address.  [All of this
   * stuff happens when the INIT ACK arrives.  This is a NON-BLOCKING
   * function.]
   *
   * Mandatory attributes:
   *
   * o local SCTP instance name - obtained from the INITIALIZE operation.
   *   [This is the argument asoc.]
   * o destination transport addr - specified as one of the transport
   * addresses of the peer endpoint with which the association is to be
   * established.
   *  [This is asoc->peer.active_path.]
   * o outbound stream count - the number of outbound streams the ULP
   * would like to open towards this peer endpoint.
   * [BUG: This is not currently implemented.]
   * Optional attributes:
   *
   * None.
   *
   * The return value is a disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
4671
4672
4673
4674
4675
4676
  enum sctp_disposition sctp_sf_do_prm_asoc(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4677
  {
26ac8e5fe   wangweidong   sctp: fix checkpa...
4678
  	struct sctp_association *my_asoc;
172a1599b   Xin Long   sctp: remove the ...
4679
  	struct sctp_chunk *repl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
  
  	/* The comment below says that we enter COOKIE-WAIT AFTER
  	 * sending the INIT, but that doesn't actually work in our
  	 * implementation...
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
  
  	/* RFC 2960 5.1 Normal Establishment of an Association
  	 *
  	 * A) "A" first sends an INIT chunk to "Z".  In the INIT, "A"
  	 * must provide its Verification Tag (Tag_A) in the Initiate
  	 * Tag field.  Tag_A SHOULD be a random number in the range of
  	 * 1 to 4294967295 (see 5.3.1 for Tag value selection). ...
  	 */
  
  	repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
  	if (!repl)
  		goto nomem;
405426f6c   Daniel Borkmann   net: sctp: sctp_s...
4699
4700
4701
  	/* Choose transport for INIT. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
  			SCTP_CHUNK(repl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4702
4703
4704
  	/* Cast away the const modifier, as we want to just
  	 * rerun it through as a sideffect.
  	 */
ab38fb04c   Vlad Yasevich   [SCTP]: Fix compi...
4705
4706
  	my_asoc = (struct sctp_association *)asoc;
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
  
  	/* After sending the INIT, "A" starts the T1-init timer and
  	 * enters the COOKIE-WAIT state.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Process the SEND primitive.
   *
   * Section: 10.1 ULP-to-SCTP
   * E) Send
   *
   * Format: SEND(association id, buffer address, byte count [,context]
   *         [,stream id] [,life time] [,destination transport address]
   *         [,unorder flag] [,no-bundle flag] [,payload protocol-id] )
   * -> result
   *
   * This is the main method to send user data via SCTP.
   *
   * Mandatory attributes:
   *
   *  o association id - local handle to the SCTP association
   *
   *  o buffer address - the location where the user message to be
   *    transmitted is stored;
   *
   *  o byte count - The size of the user data in number of bytes;
   *
   * Optional attributes:
   *
   *  o context - an optional 32 bit integer that will be carried in the
   *    sending failure notification to the ULP if the transportation of
   *    this User Message fails.
   *
   *  o stream id - to indicate which stream to send the data on. If not
   *    specified, stream 0 will be used.
   *
   *  o life time - specifies the life time of the user data. The user data
   *    will not be sent by SCTP after the life time expires. This
   *    parameter can be used to avoid efforts to transmit stale
   *    user messages. SCTP notifies the ULP if the data cannot be
   *    initiated to transport (i.e. sent to the destination via SCTP's
   *    send primitive) within the life time variable. However, the
   *    user data will be transmitted if SCTP has attempted to transmit a
   *    chunk before the life time expired.
   *
   *  o destination transport address - specified as one of the destination
   *    transport addresses of the peer endpoint to which this packet
   *    should be sent. Whenever possible, SCTP should use this destination
   *    transport address for sending the packets, instead of the current
   *    primary path.
   *
   *  o unorder flag - this flag, if present, indicates that the user
   *    would like the data delivered in an unordered fashion to the peer
   *    (i.e., the U flag is set to 1 on all DATA chunks carrying this
   *    message).
   *
   *  o no-bundle flag - instructs SCTP not to bundle this user data with
   *    other outbound DATA chunks. SCTP MAY still bundle even when
   *    this flag is present, when faced with network congestion.
   *
   *  o payload protocol-id - A 32 bit unsigned integer that is to be
   *    passed to the peer indicating the type of payload protocol data
   *    being transmitted. This value is passed as opaque data by SCTP.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
4781
4782
4783
4784
4785
4786
  enum sctp_disposition sctp_sf_do_prm_send(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4787
  {
9c5c62be2   Vlad Yasevich   sctp: Send user m...
4788
  	struct sctp_datamsg *msg = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4789

9c5c62be2   Vlad Yasevich   sctp: Send user m...
4790
  	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_MSG, SCTP_DATAMSG(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * Process the SHUTDOWN primitive.
   *
   * Section: 10.1:
   * C) Shutdown
   *
   * Format: SHUTDOWN(association id)
   * -> result
   *
   * Gracefully closes an association. Any locally queued user data
   * will be delivered to the peer. The association will be terminated only
   * after the peer acknowledges all the SCTP packets sent.  A success code
   * will be returned on successful termination of the association. If
   * attempting to terminate the association results in a failure, an error
   * code shall be returned.
   *
   * Mandatory attributes:
   *
   *  o association id - local handle to the SCTP association
   *
   * Optional attributes:
   *
   * None.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
4820
4821
4822
4823
4824
4825
4826
  enum sctp_disposition sctp_sf_do_9_2_prm_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4827
  {
172a1599b   Xin Long   sctp: remove the ...
4828
  	enum sctp_disposition disposition;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
  
  	/* From 9.2 Shutdown of an Association
  	 * Upon receipt of the SHUTDOWN primitive from its upper
  	 * layer, the endpoint enters SHUTDOWN-PENDING state and
  	 * remains there until all outstanding data has been
  	 * acknowledged by its peer. The endpoint accepts no new data
  	 * from its upper layer, but retransmits data to the far end
  	 * if necessary to fill gaps.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4840
4841
  	disposition = SCTP_DISPOSITION_CONSUME;
  	if (sctp_outq_is_empty(&asoc->outqueue)) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4842
  		disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4843
4844
  							    arg, commands);
  	}
172a1599b   Xin Long   sctp: remove the ...
4845

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
  	return disposition;
  }
  
  /*
   * Process the ABORT primitive.
   *
   * Section: 10.1:
   * C) Abort
   *
   * Format: Abort(association id [, cause code])
   * -> result
   *
   * Ungracefully closes an association. Any locally queued user data
   * will be discarded and an ABORT chunk is sent to the peer.  A success code
   * will be returned on successful abortion of the association. If
   * attempting to abort the association results in a failure, an error
   * code shall be returned.
   *
   * Mandatory attributes:
   *
   *  o association id - local handle to the SCTP association
   *
   * Optional attributes:
   *
   *  o cause code - reason of the abort to be passed to the peer
   *
   * None.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
4876
4877
4878
4879
4880
4881
4882
  enum sctp_disposition sctp_sf_do_9_1_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4883
4884
4885
4886
4887
4888
4889
4890
4891
  {
  	/* From 9.1 Abort of an Association
  	 * Upon receipt of the ABORT primitive from its upper
  	 * layer, the endpoint enters CLOSED state and
  	 * discard all outstanding data has been
  	 * acknowledged by its peer. The endpoint accepts no new data
  	 * from its upper layer, but retransmits data to the far end
  	 * if necessary to fill gaps.
  	 */
c164a9ba0   Sridhar Samudrala   Fix sctp privileg...
4892
  	struct sctp_chunk *abort = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4893

068d8bd33   Xin Long   sctp: sctp should...
4894
4895
  	if (abort)
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4896
4897
4898
4899
  
  	/* Even if we can't send the ABORT due to low memory delete the
  	 * TCB.  This is a departure from our typical NOMEM handling.
  	 */
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
4900
4901
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  			SCTP_ERROR(ECONNABORTED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4902
4903
  	/* Delete the established association. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
4904
  			SCTP_PERR(SCTP_ERROR_USER_ABORT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4905

b01a24078   Eric W. Biederman   sctp: Make the mi...
4906
4907
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4908

649621e3d   Marcelo Ricardo Leitner   sctp: fix use-aft...
4909
  	return SCTP_DISPOSITION_ABORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4910
4911
4912
  }
  
  /* We tried an illegal operation on an association which is closed.  */
172a1599b   Xin Long   sctp: remove the ...
4913
4914
4915
4916
4917
4918
  enum sctp_disposition sctp_sf_error_closed(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4919
4920
4921
4922
4923
4924
4925
4926
  {
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR, SCTP_ERROR(-EINVAL));
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /* We tried an illegal operation on an association which is shutting
   * down.
   */
172a1599b   Xin Long   sctp: remove the ...
4927
4928
4929
4930
4931
4932
4933
  enum sctp_disposition sctp_sf_error_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
  {
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR,
  			SCTP_ERROR(-ESHUTDOWN));
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * sctp_cookie_wait_prm_shutdown
   *
   * Section: 4 Note: 2
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explicitly address this issue, but is the route through the
   * state table when someone issues a shutdown while in COOKIE_WAIT state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
4954
4955
4956
4957
4958
4959
4960
  enum sctp_disposition sctp_sf_cookie_wait_prm_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4961
4962
4963
4964
4965
4966
  {
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_CLOSED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
4967
  	SCTP_INC_STATS(net, SCTP_MIB_SHUTDOWNS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
  
  	return SCTP_DISPOSITION_DELETE_TCB;
  }
  
  /*
   * sctp_cookie_echoed_prm_shutdown
   *
   * Section: 4 Note: 2
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explcitly address this issue, but is the route through the
   * state table when someone issues a shutdown while in COOKIE_ECHOED state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
4988
4989
4990
4991
4992
4993
4994
  enum sctp_disposition sctp_sf_cookie_echoed_prm_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4995
4996
4997
4998
  {
  	/* There is a single T1 timer, so we should be able to use
  	 * common function with the COOKIE-WAIT state.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
4999
  	return sctp_sf_cookie_wait_prm_shutdown(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
  }
  
  /*
   * sctp_sf_cookie_wait_prm_abort
   *
   * Section: 4 Note: 2
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explicitly address this issue, but is the route through the
   * state table when someone issues an abort while in COOKIE_WAIT state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
5016
5017
5018
5019
5020
5021
5022
  enum sctp_disposition sctp_sf_cookie_wait_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5023
  {
c164a9ba0   Sridhar Samudrala   Fix sctp privileg...
5024
  	struct sctp_chunk *abort = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5025
5026
5027
5028
  
  	/* Stop T1-init timer */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5029

068d8bd33   Xin Long   sctp: sctp should...
5030
5031
  	if (abort)
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5032
5033
5034
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_CLOSED));
b01a24078   Eric W. Biederman   sctp: Make the mi...
5035
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5036
5037
5038
5039
  
  	/* Even if we can't send the ABORT due to low memory delete the
  	 * TCB.  This is a departure from our typical NOMEM handling.
  	 */
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5040
5041
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  			SCTP_ERROR(ECONNREFUSED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5042
5043
  	/* Delete the established association. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
dc251b2b1   Al Viro   [SCTP]: SCTP_CMD_...
5044
  			SCTP_PERR(SCTP_ERROR_USER_ABORT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5045

649621e3d   Marcelo Ricardo Leitner   sctp: fix use-aft...
5046
  	return SCTP_DISPOSITION_ABORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
  }
  
  /*
   * sctp_sf_cookie_echoed_prm_abort
   *
   * Section: 4 Note: 3
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explcitly address this issue, but is the route through the
   * state table when someone issues an abort while in COOKIE_ECHOED state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
5063
5064
5065
5066
5067
5068
5069
  enum sctp_disposition sctp_sf_cookie_echoed_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5070
5071
5072
5073
  {
  	/* There is a single T1 timer, so we should be able to use
  	 * common function with the COOKIE-WAIT state.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5074
  	return sctp_sf_cookie_wait_prm_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
  }
  
  /*
   * sctp_sf_shutdown_pending_prm_abort
   *
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explicitly address this issue, but is the route through the
   * state table when someone issues an abort while in SHUTDOWN-PENDING state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
5089
5090
5091
5092
5093
5094
5095
  enum sctp_disposition sctp_sf_shutdown_pending_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5096
5097
5098
5099
  {
  	/* Stop the T5-shutdown guard timer.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5100
  	return sctp_sf_do_9_1_prm_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
  }
  
  /*
   * sctp_sf_shutdown_sent_prm_abort
   *
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explicitly address this issue, but is the route through the
   * state table when someone issues an abort while in SHUTDOWN-SENT state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
5115
5116
5117
5118
5119
5120
5121
  enum sctp_disposition sctp_sf_shutdown_sent_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5122
5123
5124
5125
5126
5127
5128
5129
  {
  	/* Stop the T2-shutdown timer.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  
  	/* Stop the T5-shutdown guard timer.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5130
  	return sctp_sf_do_9_1_prm_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
  }
  
  /*
   * sctp_sf_cookie_echoed_prm_abort
   *
   * Inputs
   * (endpoint, asoc)
   *
   * The RFC does not explcitly address this issue, but is the route through the
   * state table when someone issues an abort while in COOKIE_ECHOED state.
   *
   * Outputs
   * (timers)
   */
172a1599b   Xin Long   sctp: remove the ...
5145
5146
5147
5148
5149
5150
5151
  enum sctp_disposition sctp_sf_shutdown_ack_sent_prm_abort(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5152
5153
5154
5155
  {
  	/* The same T2 timer, so we should be able to use
  	 * common function with the SHUTDOWN-SENT state.
  	 */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5156
  	return sctp_sf_shutdown_sent_prm_abort(net, ep, asoc, type, arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
  }
  
  /*
   * Process the REQUESTHEARTBEAT primitive
   *
   * 10.1 ULP-to-SCTP
   * J) Request Heartbeat
   *
   * Format: REQUESTHEARTBEAT(association id, destination transport address)
   *
   * -> result
   *
   * Instructs the local endpoint to perform a HeartBeat on the specified
   * destination transport address of the given association. The returned
   * result should indicate whether the transmission of the HEARTBEAT
   * chunk to the destination address is successful.
   *
   * Mandatory attributes:
   *
   * o association id - local handle to the SCTP association
   *
   * o destination transport address - the transport address of the
   *   association on which a heartbeat should be issued.
   */
172a1599b   Xin Long   sctp: remove the ...
5181
  enum sctp_disposition sctp_sf_do_prm_requestheartbeat(
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5182
  					struct net *net,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5183
5184
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
bfc6f8270   Xin Long   sctp: remove the ...
5185
  					const union sctp_subtype type,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5186
  					void *arg,
a85bbeb22   Xin Long   sctp: remove the ...
5187
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5188
  {
fb78525ae   Vlad Yasevich   [SCTP]: Increment...
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
  	if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type,
  				      (struct sctp_transport *)arg, commands))
  		return SCTP_DISPOSITION_NOMEM;
  
  	/*
  	 * RFC 2960 (bis), section 8.3
  	 *
  	 *    D) Request an on-demand HEARTBEAT on a specific destination
  	 *    transport address of a given association.
  	 *
  	 *    The endpoint should increment the respective error  counter of
  	 *    the destination transport address each time a HEARTBEAT is sent
  	 *    to that address and not acknowledged within one RTO.
  	 *
  	 */
7e99013a5   Vlad Yasevich   sctp: Fix broken ...
5204
  	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
fb78525ae   Vlad Yasevich   [SCTP]: Increment...
5205
5206
  			SCTP_TRANSPORT(arg));
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5207
5208
5209
5210
5211
5212
5213
  }
  
  /*
   * ADDIP Section 4.1 ASCONF Chunk Procedures
   * When an endpoint has an ASCONF signaled change to be sent to the
   * remote endpoint it should do A1 to A9
   */
172a1599b   Xin Long   sctp: remove the ...
5214
5215
5216
5217
5218
5219
  enum sctp_disposition sctp_sf_do_prm_asconf(struct net *net,
  					    const struct sctp_endpoint *ep,
  					    const struct sctp_association *asoc,
  					    const union sctp_subtype type,
  					    void *arg,
  					    struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5220
5221
5222
5223
5224
5225
5226
5227
5228
  {
  	struct sctp_chunk *chunk = arg;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
  	return SCTP_DISPOSITION_CONSUME;
  }
7a090b045   Xin Long   sctp: add stream ...
5229
  /* RE-CONFIG Section 5.1 RECONF Chunk Procedures */
172a1599b   Xin Long   sctp: remove the ...
5230
5231
5232
5233
5234
5235
  enum sctp_disposition sctp_sf_do_prm_reconf(struct net *net,
  					    const struct sctp_endpoint *ep,
  					    const struct sctp_association *asoc,
  					    const union sctp_subtype type,
  					    void *arg,
  					    struct sctp_cmd_seq *commands)
7a090b045   Xin Long   sctp: add stream ...
5236
5237
5238
5239
5240
5241
  {
  	struct sctp_chunk *chunk = arg;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
  	return SCTP_DISPOSITION_CONSUME;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5242
5243
5244
5245
5246
  /*
   * Ignore the primitive event
   *
   * The return value is the disposition of the primitive.
   */
172a1599b   Xin Long   sctp: remove the ...
5247
5248
5249
5250
5251
5252
5253
  enum sctp_disposition sctp_sf_ignore_primitive(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5254
  {
bb33381d0   Daniel Borkmann   net: sctp: rework...
5255
5256
5257
  	pr_debug("%s: primitive type:%d is ignored
  ", __func__,
  		 type.primitive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5258
5259
5260
5261
5262
5263
5264
5265
  	return SCTP_DISPOSITION_DISCARD;
  }
  
  /***************************************************************************
   * These are the state functions for the OTHER events.
   ***************************************************************************/
  
  /*
e1cdd553d   Wei Yongjun   sctp: implement e...
5266
5267
5268
5269
5270
   * When the SCTP stack has no more user data to send or retransmit, this
   * notification is given to the user. Also, at the time when a user app
   * subscribes to this event, if there is no data to be sent or
   * retransmit, the stack will immediately send up this notification.
   */
172a1599b   Xin Long   sctp: remove the ...
5271
5272
5273
5274
5275
5276
5277
  enum sctp_disposition sctp_sf_do_no_pending_tsn(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
e1cdd553d   Wei Yongjun   sctp: implement e...
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
  {
  	struct sctp_ulpevent *event;
  
  	event = sctp_ulpevent_make_sender_dry_event(asoc, GFP_ATOMIC);
  	if (!event)
  		return SCTP_DISPOSITION_NOMEM;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(event));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
   * Start the shutdown negotiation.
   *
   * From Section 9.2:
   * Once all its outstanding data has been acknowledged, the endpoint
   * shall send a SHUTDOWN chunk to its peer including in the Cumulative
   * TSN Ack field the last sequential TSN it has received from the peer.
   * It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT
   * state. If the timer expires, the endpoint must re-send the SHUTDOWN
   * with the updated last sequential TSN received from its peer.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
5303
5304
5305
5306
5307
5308
5309
  enum sctp_disposition sctp_sf_do_9_2_start_shutdown(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5310
5311
5312
5313
5314
5315
5316
5317
  {
  	struct sctp_chunk *reply;
  
  	/* Once all its outstanding data has been acknowledged, the
  	 * endpoint shall send a SHUTDOWN chunk to its peer including
  	 * in the Cumulative TSN Ack field the last sequential TSN it
  	 * has received from the peer.
  	 */
145cb2f71   Jere Leppänen   sctp: Fix bundlin...
5318
  	reply = sctp_make_shutdown(asoc, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
  	if (!reply)
  		goto nomem;
  
  	/* Set the transport for the SHUTDOWN chunk and the timeout for the
  	 * T2-shutdown timer.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
  
  	/* It shall then start the T2-shutdown timer */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
536428a9b   Wei Yongjun   sctp: Fix to star...
5330
5331
5332
5333
  	/* RFC 4960 Section 9.2
  	 * The sender of the SHUTDOWN MAY also start an overall guard timer
  	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
  	 */
f8d960524   Thomas Graf   sctp: Enforce ret...
5334
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
536428a9b   Wei Yongjun   sctp: Fix to star...
5335
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
9f70f46bd   Neil Horman   sctp: properly la...
5336
  	if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
  
  	/* and enter the SHUTDOWN-SENT state.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_SHUTDOWN_SENT));
  
  	/* sctp-implguide 2.10 Issues with Heartbeating and failover
  	 *
  	 * HEARTBEAT ... is discontinued after sending either SHUTDOWN
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
5347
  	 * or SHUTDOWN-ACK.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Generate a SHUTDOWN ACK now that everything is SACK'd.
   *
   * From Section 9.2:
   *
   * If it has no more outstanding DATA chunks, the SHUTDOWN receiver
   * shall send a SHUTDOWN ACK and start a T2-shutdown timer of its own,
   * entering the SHUTDOWN-ACK-SENT state. If the timer expires, the
   * endpoint must re-send the SHUTDOWN ACK.
   *
   * The return value is the disposition.
   */
172a1599b   Xin Long   sctp: remove the ...
5371
5372
5373
5374
5375
5376
5377
  enum sctp_disposition sctp_sf_do_9_2_shutdown_ack(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5378
  {
172a1599b   Xin Long   sctp: remove the ...
5379
  	struct sctp_chunk *chunk = arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
  	struct sctp_chunk *reply;
  
  	/* There are 2 ways of getting here:
  	 *    1) called in response to a SHUTDOWN chunk
  	 *    2) called when SCTP_EVENT_NO_PENDING_TSN event is issued.
  	 *
  	 * For the case (2), the arg parameter is set to NULL.  We need
  	 * to check that we have a chunk before accessing it's fields.
  	 */
  	if (chunk) {
  		if (!sctp_vtag_verify(chunk, asoc))
ac23e6813   Xin Long   sctp: fix the nam...
5391
5392
  			return sctp_sf_pdiscard(net, ep, asoc, type, arg,
  						commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5393
5394
  
  		/* Make sure that the SHUTDOWN chunk has a valid length. */
ac23e6813   Xin Long   sctp: fix the nam...
5395
5396
5397
5398
  		if (!sctp_chunk_length_valid(
  				chunk, sizeof(struct sctp_shutdown_chunk)))
  			return sctp_sf_violation_chunklen(net, ep, asoc, type,
  							  arg, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
  	}
  
  	/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
  	 * shall send a SHUTDOWN ACK ...
  	 */
  	reply = sctp_make_shutdown_ack(asoc, chunk);
  	if (!reply)
  		goto nomem;
  
  	/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
  	 * the T2-shutdown timer.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
  
  	/* and start/restart a T2-shutdown timer of its own, */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
9f70f46bd   Neil Horman   sctp: properly la...
5416
  	if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
  
  	/* Enter the SHUTDOWN-ACK-SENT state.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_SHUTDOWN_ACK_SENT));
  
  	/* sctp-implguide 2.10 Issues with Heartbeating and failover
  	 *
  	 * HEARTBEAT ... is discontinued after sending either SHUTDOWN
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
5427
  	 * or SHUTDOWN-ACK.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * Ignore the event defined as other
   *
   * The return value is the disposition of the event.
   */
172a1599b   Xin Long   sctp: remove the ...
5444
5445
5446
5447
5448
5449
  enum sctp_disposition sctp_sf_ignore_other(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5450
  {
bb33381d0   Daniel Borkmann   net: sctp: rework...
5451
5452
5453
  	pr_debug("%s: the event other type:%d is ignored
  ",
  		 __func__, type.other);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
  	return SCTP_DISPOSITION_DISCARD;
  }
  
  /************************************************************
   * These are the state functions for handling timeout events.
   ************************************************************/
  
  /*
   * RTX Timeout
   *
   * Section: 6.3.3 Handle T3-rtx Expiration
   *
   * Whenever the retransmission timer T3-rtx expires for a destination
   * address, do the following:
   * [See below]
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
5472
5473
5474
5475
5476
5477
  enum sctp_disposition sctp_sf_do_6_3_3_rtx(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5478
5479
  {
  	struct sctp_transport *transport = arg;
b01a24078   Eric W. Biederman   sctp: Make the mi...
5480
  	SCTP_INC_STATS(net, SCTP_MIB_T3_RTX_EXPIREDS);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
5481

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5482
  	if (asoc->overall_error_count >= asoc->max_retrans) {
8a0d19c5e   lucien   sctp: start t5 ti...
5483
5484
  		if (asoc->peer.zero_window_announced &&
  		    asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
f8d960524   Thomas Graf   sctp: Enforce ret...
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
  			/*
  			 * We are here likely because the receiver had its rwnd
  			 * closed for a while and we have not been able to
  			 * transmit the locally queued data within the maximum
  			 * retransmission attempts limit.  Start the T5
  			 * shutdown guard timer to give the receiver one last
  			 * chance and some additional time to recover before
  			 * aborting.
  			 */
  			sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
  		} else {
  			sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  					SCTP_ERROR(ETIMEDOUT));
  			/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
  			sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
  					SCTP_PERR(SCTP_ERROR_NO_ERROR));
b01a24078   Eric W. Biederman   sctp: Make the mi...
5502
5503
  			SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  			SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
f8d960524   Thomas Graf   sctp: Enforce ret...
5504
5505
  			return SCTP_DISPOSITION_DELETE_TCB;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
  	}
  
  	/* E1) For the destination address for which the timer
  	 * expires, adjust its ssthresh with rules defined in Section
  	 * 7.2.3 and set the cwnd <- MTU.
  	 */
  
  	/* E2) For the destination address for which the timer
  	 * expires, set RTO <- RTO * 2 ("back off the timer").  The
  	 * maximum value discussed in rule C7 above (RTO.max) may be
  	 * used to provide an upper bound to this doubling operation.
  	 */
  
  	/* E3) Determine how many of the earliest (i.e., lowest TSN)
  	 * outstanding DATA chunks for the address for which the
  	 * T3-rtx has expired will fit into a single packet, subject
  	 * to the MTU constraint for the path corresponding to the
  	 * destination transport address to which the retransmission
  	 * is being sent (this may be different from the address for
  	 * which the timer expires [see Section 6.4]).  Call this
  	 * value K. Bundle and retransmit those K DATA chunks in a
  	 * single packet to the destination endpoint.
  	 *
  	 * Note: Any DATA chunks that were sent to the address for
  	 * which the T3-rtx timer expired but did not fit in one MTU
  	 * (rule E3 above), should be marked for retransmission and
  	 * sent as soon as cwnd allows (normally when a SACK arrives).
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5534
5535
  	/* Do some failure management (Section 8.2). */
  	sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
1845a579e   Vlad Yasevich   [SCTP]: Strike th...
5536
5537
  	/* NB: Rules E4 and F1 are implicit in R1.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(transport));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * Generate delayed SACK on timeout
   *
   * Section: 6.2  Acknowledgement on Reception of DATA Chunks
   *
   * The guidelines on delayed acknowledgement algorithm specified in
   * Section 4.2 of [RFC2581] SHOULD be followed.  Specifically, an
   * acknowledgement SHOULD be generated for at least every second packet
   * (not every second DATA chunk) received, and SHOULD be generated
   * within 200 ms of the arrival of any unacknowledged DATA chunk.  In
   * some situations it may be beneficial for an SCTP transmitter to be
   * more conservative than the algorithms detailed in this document
   * allow. However, an SCTP transmitter MUST NOT be more aggressive than
   * the following algorithms allow.
   */
172a1599b   Xin Long   sctp: remove the ...
5556
5557
5558
5559
5560
5561
  enum sctp_disposition sctp_sf_do_6_2_sack(struct net *net,
  					  const struct sctp_endpoint *ep,
  					  const struct sctp_association *asoc,
  					  const union sctp_subtype type,
  					  void *arg,
  					  struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5562
  {
b01a24078   Eric W. Biederman   sctp: Make the mi...
5563
  	SCTP_INC_STATS(net, SCTP_MIB_DELAY_SACK_EXPIREDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5564
5565
5566
5567
5568
  	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5569
   * sctp_sf_t1_init_timer_expire
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
   *
   * Section: 4 Note: 2
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   *  RFC 2960 Section 4 Notes
   *  2) If the T1-init timer expires, the endpoint MUST retransmit INIT
   *     and re-start the T1-init timer without changing state.  This MUST
   *     be repeated up to 'Max.Init.Retransmits' times.  After that, the
   *     endpoint MUST abort the initialization process and report the
   *     error to SCTP user.
   *
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5583
5584
5585
5586
   * Outputs
   * (timers, events)
   *
   */
172a1599b   Xin Long   sctp: remove the ...
5587
5588
5589
5590
5591
5592
5593
  enum sctp_disposition sctp_sf_t1_init_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5594
  {
172a1599b   Xin Long   sctp: remove the ...
5595
  	int attempts = asoc->init_err_counter + 1;
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5596
5597
  	struct sctp_chunk *repl = NULL;
  	struct sctp_bind_addr *bp;
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5598

bb33381d0   Daniel Borkmann   net: sctp: rework...
5599
5600
  	pr_debug("%s: timer T1 expired (INIT)
  ", __func__);
b01a24078   Eric W. Biederman   sctp: Make the mi...
5601
  	SCTP_INC_STATS(net, SCTP_MIB_T1_INIT_EXPIREDS);
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5602

81845c21d   Vlad Yasevich   [SCTP]: correct t...
5603
  	if (attempts <= asoc->max_init_attempts) {
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
  		bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
  		repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
  		if (!repl)
  			return SCTP_DISPOSITION_NOMEM;
  
  		/* Choose transport for INIT. */
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
  				SCTP_CHUNK(repl));
  
  		/* Issue a sideeffect to do the needed accounting. */
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
  
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  	} else {
bb33381d0   Daniel Borkmann   net: sctp: rework...
5619
5620
5621
5622
  		pr_debug("%s: giving up on INIT, attempts:%d "
  			 "max_init_attempts:%d
  ", __func__, attempts,
  			 asoc->max_init_attempts);
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5623
5624
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5625
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
dc251b2b1   Al Viro   [SCTP]: SCTP_CMD_...
5626
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /*
   * sctp_sf_t1_cookie_timer_expire
   *
   * Section: 4 Note: 2
   * Verification Tag:
   * Inputs
   * (endpoint, asoc)
   *
   *  RFC 2960 Section 4 Notes
   *  3) If the T1-cookie timer expires, the endpoint MUST retransmit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5643
5644
5645
5646
5647
5648
5649
5650
5651
   *     COOKIE ECHO and re-start the T1-cookie timer without changing
   *     state.  This MUST be repeated up to 'Max.Init.Retransmits' times.
   *     After that, the endpoint MUST abort the initialization process and
   *     report the error to SCTP user.
   *
   * Outputs
   * (timers, events)
   *
   */
172a1599b   Xin Long   sctp: remove the ...
5652
5653
5654
5655
5656
5657
5658
  enum sctp_disposition sctp_sf_t1_cookie_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5659
  {
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5660
  	int attempts = asoc->init_err_counter + 1;
172a1599b   Xin Long   sctp: remove the ...
5661
  	struct sctp_chunk *repl = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5662

bb33381d0   Daniel Borkmann   net: sctp: rework...
5663
5664
  	pr_debug("%s: timer T1 expired (COOKIE-ECHO)
  ", __func__);
b01a24078   Eric W. Biederman   sctp: Make the mi...
5665
  	SCTP_INC_STATS(net, SCTP_MIB_T1_COOKIE_EXPIREDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5666

81845c21d   Vlad Yasevich   [SCTP]: correct t...
5667
  	if (attempts <= asoc->max_init_attempts) {
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5668
  		repl = sctp_make_cookie_echo(asoc, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5669
  		if (!repl)
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5670
  			return SCTP_DISPOSITION_NOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5671

96cd0d3d7   Vlad Yasevich   sctp: enable cook...
5672
5673
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
  				SCTP_CHUNK(repl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5674
  		/* Issue a sideeffect to do the needed accounting. */
3f7a87d2f   Frank Filz   [SCTP] sctp_conne...
5675
5676
  		sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5677
5678
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
  	} else {
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5679
5680
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5681
  		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
dc251b2b1   Al Viro   [SCTP]: SCTP_CMD_...
5682
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5683
5684
5685
5686
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
  
  	return SCTP_DISPOSITION_CONSUME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
  }
  
  /* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
   * with the updated last sequential TSN received from its peer.
   *
   * An endpoint should limit the number of retransmissions of the
   * SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.
   * If this threshold is exceeded the endpoint should destroy the TCB and
   * MUST report the peer endpoint unreachable to the upper layer (and
   * thus the association enters the CLOSED state).  The reception of any
   * packet from its peer (i.e. as the peer sends all of its queued DATA
   * chunks) should clear the endpoint's retransmission count and restart
   * the T2-Shutdown timer,  giving its peer ample opportunity to transmit
   * all of its queued DATA chunks that have not yet been sent.
   */
172a1599b   Xin Long   sctp: remove the ...
5702
5703
5704
5705
5706
5707
5708
  enum sctp_disposition sctp_sf_t2_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5709
5710
  {
  	struct sctp_chunk *reply = NULL;
bb33381d0   Daniel Borkmann   net: sctp: rework...
5711
5712
  	pr_debug("%s: timer T2 expired
  ", __func__);
b01a24078   Eric W. Biederman   sctp: Make the mi...
5713
  	SCTP_INC_STATS(net, SCTP_MIB_T2_SHUTDOWN_EXPIREDS);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
5714

58fbbed4f   Neil Horman   [SCTP]: extend ex...
5715
  	((struct sctp_association *)asoc)->shutdown_retries++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5716
  	if (asoc->overall_error_count >= asoc->max_retrans) {
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5717
5718
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5719
5720
  		/* Note:  CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
5721
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
b01a24078   Eric W. Biederman   sctp: Make the mi...
5722
5723
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
  		return SCTP_DISPOSITION_DELETE_TCB;
  	}
  
  	switch (asoc->state) {
  	case SCTP_STATE_SHUTDOWN_SENT:
  		reply = sctp_make_shutdown(asoc, NULL);
  		break;
  
  	case SCTP_STATE_SHUTDOWN_ACK_SENT:
  		reply = sctp_make_shutdown_ack(asoc, NULL);
  		break;
  
  	default:
  		BUG();
  		break;
3ff50b799   Stephen Hemminger   [NET]: cleanup ex...
5739
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5740
5741
5742
  
  	if (!reply)
  		goto nomem;
6345b1998   Wei Yongjun   sctp: fix panic w...
5743
5744
5745
5746
5747
5748
5749
  	/* Do some failure management (Section 8.2).
  	 * If we remove the transport an SHUTDOWN was last sent to, don't
  	 * do failure management.
  	 */
  	if (asoc->shutdown_last_sent_to)
  		sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
  				SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
  
  	/* Set the transport for the SHUTDOWN/ACK chunk and the timeout for
  	 * the T2-shutdown timer.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
  
  	/* Restart the T2-shutdown timer.  */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
  	return SCTP_DISPOSITION_CONSUME;
  
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /*
   * ADDIP Section 4.1 ASCONF CHunk Procedures
   * If the T4 RTO timer expires the endpoint should do B1 to B5
   */
172a1599b   Xin Long   sctp: remove the ...
5770
5771
5772
5773
5774
5775
5776
  enum sctp_disposition sctp_sf_t4_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5777
5778
5779
  {
  	struct sctp_chunk *chunk = asoc->addip_last_asconf;
  	struct sctp_transport *transport = chunk->transport;
b01a24078   Eric W. Biederman   sctp: Make the mi...
5780
  	SCTP_INC_STATS(net, SCTP_MIB_T4_RTO_EXPIREDS);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
5781

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5782
5783
5784
5785
  	/* ADDIP 4.1 B1) Increment the error counters and perform path failure
  	 * detection on the appropriate destination address as defined in
  	 * RFC2960 [5] section 8.1 and 8.2.
  	 */
10a43cea7   Wei Yongjun   sctp: fix panic w...
5786
5787
5788
  	if (transport)
  		sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
  				SCTP_TRANSPORT(transport));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
  
  	/* Reconfig T4 timer and transport. */
  	sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
  
  	/* ADDIP 4.1 B2) Increment the association error counters and perform
  	 * endpoint failure detection on the association as defined in
  	 * RFC2960 [5] section 8.1 and 8.2.
  	 * association error counter is incremented in SCTP_CMD_STRIKE.
  	 */
  	if (asoc->overall_error_count >= asoc->max_retrans) {
  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
  				SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5801
5802
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5803
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
5804
  				SCTP_PERR(SCTP_ERROR_NO_ERROR));
b01a24078   Eric W. Biederman   sctp: Make the mi...
5805
5806
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
  		return SCTP_DISPOSITION_ABORT;
  	}
  
  	/* ADDIP 4.1 B3) Back-off the destination address RTO value to which
  	 * the ASCONF chunk was sent by doubling the RTO timer value.
  	 * This is done in SCTP_CMD_STRIKE.
  	 */
  
  	/* ADDIP 4.1 B4) Re-transmit the ASCONF Chunk last sent and if possible
  	 * choose an alternate destination address (please refer to RFC2960
  	 * [5] section 6.4.1). An endpoint MUST NOT add new parameters to this
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
5818
  	 * chunk, it MUST be the same (including its serial number) as the last
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
  	 * ASCONF sent.
  	 */
  	sctp_chunk_hold(asoc->addip_last_asconf);
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  			SCTP_CHUNK(asoc->addip_last_asconf));
  
  	/* ADDIP 4.1 B5) Restart the T-4 RTO timer. Note that if a different
  	 * destination is selected, then the RTO used will be that of the new
  	 * destination address.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
  			SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
  
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /* sctpimpguide-05 Section 2.12.2
   * The sender of the SHUTDOWN MAY also start an overall guard timer
   * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
   * At the expiration of this timer the sender SHOULD abort the association
   * by sending an ABORT chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
5841
5842
5843
5844
5845
5846
5847
  enum sctp_disposition sctp_sf_t5_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5848
5849
  {
  	struct sctp_chunk *reply = NULL;
bb33381d0   Daniel Borkmann   net: sctp: rework...
5850
5851
  	pr_debug("%s: timer T5 expired
  ", __func__);
b01a24078   Eric W. Biederman   sctp: Make the mi...
5852
  	SCTP_INC_STATS(net, SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5853
5854
5855
5856
5857
5858
  
  	reply = sctp_make_abort(asoc, NULL, 0);
  	if (!reply)
  		goto nomem;
  
  	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
5859
5860
  	sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  			SCTP_ERROR(ETIMEDOUT));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5861
  	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
5862
  			SCTP_PERR(SCTP_ERROR_NO_ERROR));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5863

b01a24078   Eric W. Biederman   sctp: Make the mi...
5864
5865
  	SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  	SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
a1080a8b0   Vlad Yasevich   sctp: update SNMP...
5866

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
  	return SCTP_DISPOSITION_DELETE_TCB;
  nomem:
  	return SCTP_DISPOSITION_NOMEM;
  }
  
  /* Handle expiration of AUTOCLOSE timer.  When the autoclose timer expires,
   * the association is automatically closed by starting the shutdown process.
   * The work that needs to be done is same as when SHUTDOWN is initiated by
   * the user.  So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
   */
172a1599b   Xin Long   sctp: remove the ...
5877
5878
5879
5880
5881
5882
5883
  enum sctp_disposition sctp_sf_autoclose_timer_expire(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					const union sctp_subtype type,
  					void *arg,
  					struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5884
  {
172a1599b   Xin Long   sctp: remove the ...
5885
  	enum sctp_disposition disposition;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5886

b01a24078   Eric W. Biederman   sctp: Make the mi...
5887
  	SCTP_INC_STATS(net, SCTP_MIB_AUTOCLOSE_EXPIREDS);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
5888

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
  	/* From 9.2 Shutdown of an Association
  	 * Upon receipt of the SHUTDOWN primitive from its upper
  	 * layer, the endpoint enters SHUTDOWN-PENDING state and
  	 * remains there until all outstanding data has been
  	 * acknowledged by its peer. The endpoint accepts no new data
  	 * from its upper layer, but retransmits data to the far end
  	 * if necessary to fill gaps.
  	 */
  	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
  			SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5899
5900
  	disposition = SCTP_DISPOSITION_CONSUME;
  	if (sctp_outq_is_empty(&asoc->outqueue)) {
24cb81a6a   Eric W. Biederman   sctp: Push struct...
5901
  		disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
145cb2f71   Jere Leppänen   sctp: Fix bundlin...
5902
  							    NULL, commands);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5903
  	}
172a1599b   Xin Long   sctp: remove the ...
5904

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
  	return disposition;
  }
  
  /*****************************************************************************
   * These are sa state functions which could apply to all types of events.
   ****************************************************************************/
  
  /*
   * This table entry is not implemented.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
5920
5921
5922
5923
5924
  enum sctp_disposition sctp_sf_not_impl(struct net *net,
  				       const struct sctp_endpoint *ep,
  				       const struct sctp_association *asoc,
  				       const union sctp_subtype type,
  				       void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
  {
  	return SCTP_DISPOSITION_NOT_IMPL;
  }
  
  /*
   * This table entry represents a bug.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
5937
5938
5939
5940
5941
  enum sctp_disposition sctp_sf_bug(struct net *net,
  				  const struct sctp_endpoint *ep,
  				  const struct sctp_association *asoc,
  				  const union sctp_subtype type,
  				  void *arg, struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
  {
  	return SCTP_DISPOSITION_BUG;
  }
  
  /*
   * This table entry represents the firing of a timer in the wrong state.
   * Since timer deletion cannot be guaranteed a timer 'may' end up firing
   * when the association is in the wrong state.   This event should
   * be ignored, so as to prevent any rearming of the timer.
   *
   * Inputs
   * (endpoint, asoc, chunk)
   *
   * The return value is the disposition of the chunk.
   */
172a1599b   Xin Long   sctp: remove the ...
5957
5958
5959
5960
5961
5962
  enum sctp_disposition sctp_sf_timer_ignore(struct net *net,
  					   const struct sctp_endpoint *ep,
  					   const struct sctp_association *asoc,
  					   const union sctp_subtype type,
  					   void *arg,
  					   struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5963
  {
bb33381d0   Daniel Borkmann   net: sctp: rework...
5964
5965
  	pr_debug("%s: timer %d ignored
  ", __func__, type.chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
  	return SCTP_DISPOSITION_CONSUME;
  }
  
  /********************************************************************
   * 2nd Level Abstractions
   ********************************************************************/
  
  /* Pull the SACK chunk based on the SACK header. */
  static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
  {
  	struct sctp_sackhdr *sack;
172a1599b   Xin Long   sctp: remove the ...
5977
  	__u16 num_dup_tsns;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5978
5979
  	unsigned int len;
  	__u16 num_blocks;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
  
  	/* Protect ourselves from reading too far into
  	 * the skb from a bogus sender.
  	 */
  	sack = (struct sctp_sackhdr *) chunk->skb->data;
  
  	num_blocks = ntohs(sack->num_gap_ack_blocks);
  	num_dup_tsns = ntohs(sack->num_dup_tsns);
  	len = sizeof(struct sctp_sackhdr);
  	len += (num_blocks + num_dup_tsns) * sizeof(__u32);
  	if (len > chunk->skb->len)
  		return NULL;
  
  	skb_pull(chunk->skb, len);
  
  	return sack;
  }
  
  /* Create an ABORT packet to be sent as a response, with the specified
   * error causes.
   */
172a1599b   Xin Long   sctp: remove the ...
6001
6002
6003
6004
6005
6006
  static struct sctp_packet *sctp_abort_pkt_new(
  					struct net *net,
  					const struct sctp_endpoint *ep,
  					const struct sctp_association *asoc,
  					struct sctp_chunk *chunk,
  					const void *payload, size_t paylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6007
6008
6009
  {
  	struct sctp_packet *packet;
  	struct sctp_chunk *abort;
2ce955035   Eric W. Biederman   sctp: Make the ct...
6010
  	packet = sctp_ootb_pkt_new(net, asoc, chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
  
  	if (packet) {
  		/* Make an ABORT.
  		 * The T bit will be set if the asoc is NULL.
  		 */
  		abort = sctp_make_abort(asoc, chunk, paylen);
  		if (!abort) {
  			sctp_ootb_pkt_free(packet);
  			return NULL;
  		}
047a2428a   Jerome Forissier   [SCTP] Implement ...
6021
6022
6023
6024
  
  		/* Reflect vtag if T-Bit is set */
  		if (sctp_test_T_bit(abort))
  			packet->vtag = ntohl(chunk->sctp_hdr->vtag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
  		/* Add specified error causes, i.e., payload, to the
  		 * end of the chunk.
  		 */
  		sctp_addto_chunk(abort, paylen, payload);
  
  		/* Set the skb to the belonging sock for accounting.  */
  		abort->skb->sk = ep->base.sk;
  
  		sctp_packet_append_chunk(packet, abort);
  
  	}
  
  	return packet;
  }
  
  /* Allocate a packet for responding in the OOTB conditions.  */
172a1599b   Xin Long   sctp: remove the ...
6041
6042
6043
6044
  static struct sctp_packet *sctp_ootb_pkt_new(
  					struct net *net,
  					const struct sctp_association *asoc,
  					const struct sctp_chunk *chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6045
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6046
  	struct sctp_transport *transport;
172a1599b   Xin Long   sctp: remove the ...
6047
6048
  	struct sctp_packet *packet;
  	__u16 sport, dport;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
  	__u32 vtag;
  
  	/* Get the source and destination port from the inbound packet.  */
  	sport = ntohs(chunk->sctp_hdr->dest);
  	dport = ntohs(chunk->sctp_hdr->source);
  
  	/* The V-tag is going to be the same as the inbound packet if no
  	 * association exists, otherwise, use the peer's vtag.
  	 */
  	if (asoc) {
02c4e12c6   Wei Yongjun   SCTP: Send ABORT ...
6059
6060
6061
  		/* Special case the INIT-ACK as there is no peer's vtag
  		 * yet.
  		 */
cb3f837ba   wangweidong   sctp: fix checkpa...
6062
  		switch (chunk->chunk_hdr->type) {
02c4e12c6   Wei Yongjun   SCTP: Send ABORT ...
6063
6064
  		case SCTP_CID_INIT_ACK:
  		{
cb1844c47   Xin Long   sctp: remove the ...
6065
  			struct sctp_initack_chunk *initack;
02c4e12c6   Wei Yongjun   SCTP: Send ABORT ...
6066

cb1844c47   Xin Long   sctp: remove the ...
6067
  			initack = (struct sctp_initack_chunk *)chunk->chunk_hdr;
02c4e12c6   Wei Yongjun   SCTP: Send ABORT ...
6068
6069
6070
6071
6072
6073
6074
  			vtag = ntohl(initack->init_hdr.init_tag);
  			break;
  		}
  		default:
  			vtag = asoc->peer.i.init_tag;
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6075
6076
6077
6078
  	} else {
  		/* Special case the INIT and stale COOKIE_ECHO as there is no
  		 * vtag yet.
  		 */
cb3f837ba   wangweidong   sctp: fix checkpa...
6079
  		switch (chunk->chunk_hdr->type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6080
6081
  		case SCTP_CID_INIT:
  		{
01a992bea   Xin Long   sctp: remove the ...
6082
  			struct sctp_init_chunk *init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6083

01a992bea   Xin Long   sctp: remove the ...
6084
  			init = (struct sctp_init_chunk *)chunk->chunk_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6085
6086
6087
  			vtag = ntohl(init->init_hdr.init_tag);
  			break;
  		}
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
6088
  		default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6089
6090
6091
6092
6093
6094
  			vtag = ntohl(chunk->sctp_hdr->vtag);
  			break;
  		}
  	}
  
  	/* Make a transport for the bucket, Eliza... */
89bf3450c   Eric W. Biederman   sctp: Push struct...
6095
  	transport = sctp_transport_new(net, sctp_source(chunk), GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6096
6097
6098
6099
6100
6101
  	if (!transport)
  		goto nomem;
  
  	/* Cache a route for the transport with the chunk's destination as
  	 * the source address.
  	 */
16b0a0303   Al Viro   [SCTP]: Switch sc...
6102
  	sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
2ce955035   Eric W. Biederman   sctp: Make the ct...
6103
  			     sctp_sk(net->sctp.ctl_sock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6104

66b91d2cd   Marcelo Ricardo Leitner   sctp: remove retu...
6105
6106
6107
  	packet = &transport->packet;
  	sctp_packet_init(packet, transport, sport, dport);
  	sctp_packet_config(packet, vtag, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
  
  	return packet;
  
  nomem:
  	return NULL;
  }
  
  /* Free the packet allocated earlier for responding in the OOTB condition.  */
  void sctp_ootb_pkt_free(struct sctp_packet *packet)
  {
  	sctp_transport_free(packet->transport);
  }
  
  /* Send a stale cookie error when a invalid COOKIE ECHO chunk is found  */
24cb81a6a   Eric W. Biederman   sctp: Push struct...
6122
6123
  static void sctp_send_stale_cookie_err(struct net *net,
  				       const struct sctp_endpoint *ep,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6124
6125
  				       const struct sctp_association *asoc,
  				       const struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
6126
  				       struct sctp_cmd_seq *commands,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6127
6128
6129
6130
6131
  				       struct sctp_chunk *err_chunk)
  {
  	struct sctp_packet *packet;
  
  	if (err_chunk) {
2ce955035   Eric W. Biederman   sctp: Make the ct...
6132
  		packet = sctp_ootb_pkt_new(net, asoc, chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6133
6134
6135
6136
6137
6138
  		if (packet) {
  			struct sctp_signed_cookie *cookie;
  
  			/* Override the OOTB vtag from the cookie. */
  			cookie = chunk->subh.cookie_hdr;
  			packet->vtag = cookie->c.peer_vtag;
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
6139

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6140
6141
6142
6143
6144
  			/* Set the skb to the belonging sock for accounting. */
  			err_chunk->skb->sk = ep->base.sk;
  			sctp_packet_append_chunk(packet, err_chunk);
  			sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
  					SCTP_PACKET(packet));
b01a24078   Eric W. Biederman   sctp: Make the mi...
6145
  			SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6146
6147
6148
6149
6150
6151
6152
6153
6154
  		} else
  			sctp_chunk_free (err_chunk);
  	}
  }
  
  
  /* Process a data chunk */
  static int sctp_eat_data(const struct sctp_association *asoc,
  			 struct sctp_chunk *chunk,
a85bbeb22   Xin Long   sctp: remove the ...
6155
  			 struct sctp_cmd_seq *commands)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6156
  {
7c3ceb4fb   Neil Horman   [SCTP]: Allow spi...
6157
  	struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
049b3ff5a   Neil Horman   [SCTP]: Include u...
6158
  	struct sock *sk = asoc->base.sk;
24cb81a6a   Eric W. Biederman   sctp: Push struct...
6159
  	struct net *net = sock_net(sk);
172a1599b   Xin Long   sctp: remove the ...
6160
6161
6162
6163
  	struct sctp_datahdr *data_hdr;
  	struct sctp_chunk *err;
  	enum sctp_verb deliver;
  	size_t datalen;
172a1599b   Xin Long   sctp: remove the ...
6164
6165
  	__u32 tsn;
  	int tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6166

3583df1a3   Xin Long   sctp: remove the ...
6167
6168
  	data_hdr = (struct sctp_datahdr *)chunk->skb->data;
  	chunk->subh.data_hdr = data_hdr;
9d4ceaf15   Xin Long   sctp: implement v...
6169
  	skb_pull(chunk->skb, sctp_datahdr_len(&asoc->stream));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6170
6171
  
  	tsn = ntohl(data_hdr->tsn);
bb33381d0   Daniel Borkmann   net: sctp: rework...
6172
6173
  	pr_debug("%s: TSN 0x%x
  ", __func__, tsn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
  
  	/* ASSERT:  Now skb->data is really the user data.  */
  
  	/* Process ECN based congestion.
  	 *
  	 * Since the chunk structure is reused for all chunks within
  	 * a packet, we use ecn_ce_done to track if we've already
  	 * done CE processing for this packet.
  	 *
  	 * We need to do ECN processing even if we plan to discard the
  	 * chunk later.
  	 */
2d47fd120   Marcelo Ricardo Leitner   sctp: only check ...
6186
  	if (asoc->peer.ecn_capable && !chunk->ecn_ce_done) {
e7487c86d   Marcelo Ricardo Leitner   sctp: avoid ident...
6187
  		struct sctp_af *af = SCTP_INPUT_CB(chunk->skb)->af;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6188
  		chunk->ecn_ce_done = 1;
2d47fd120   Marcelo Ricardo Leitner   sctp: only check ...
6189
  		if (af->is_ce(sctp_gso_headskb(chunk->skb))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
  			/* Do real work as sideffect. */
  			sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
  					SCTP_U32(tsn));
  		}
  	}
  
  	tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
  	if (tmp < 0) {
  		/* The TSN is too high--silently discard the chunk and
  		 * count on it getting retransmitted later.
  		 */
196d67593   Michele Baldessari   sctp: Add support...
6201
6202
  		if (chunk->asoc)
  			chunk->asoc->stats.outofseqtsns++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
  		return SCTP_IERROR_HIGH_TSN;
  	} else if (tmp > 0) {
  		/* This is a duplicate.  Record it.  */
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
  		return SCTP_IERROR_DUP_TSN;
  	}
  
  	/* This is a new TSN.  */
  
  	/* Discard if there is no room in the receive window.
  	 * Actually, allow a little bit of overflow (up to a MTU).
  	 */
  	datalen = ntohs(chunk->chunk_hdr->length);
9d4ceaf15   Xin Long   sctp: implement v...
6216
  	datalen -= sctp_datachk_len(&asoc->stream);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
  
  	deliver = SCTP_CMD_CHUNK_ULP;
  
  	/* Think about partial delivery. */
  	if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
  
  		/* Even if we don't accept this chunk there is
  		 * memory pressure.
  		 */
  		sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
  	}
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
6228
  	/* Spill over rwnd a little bit.  Note: While allowed, this spill over
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6229
6230
6231
  	 * seems a bit troublesome in that frag_point varies based on
  	 * PMTU.  In cases, such as loopback, this might be a rather
  	 * large spill over.
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6232
  	 */
362d52040   Daniel Borkmann   Revert "net: sctp...
6233
  	if ((!chunk->data_accepted) && (!asoc->rwnd || asoc->rwnd_over ||
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6234
  	    (datalen > asoc->rwnd + asoc->frag_point))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6235
6236
6237
6238
6239
6240
6241
  
  		/* If this is the next TSN, consider reneging to make
  		 * room.   Note: Playing nice with a confused sender.  A
  		 * malicious sender can still eat up all our buffer
  		 * space and in the future we may want to detect and
  		 * do more drastic reneging.
  		 */
7c3ceb4fb   Neil Horman   [SCTP]: Allow spi...
6242
6243
  		if (sctp_tsnmap_has_gap(map) &&
  		    (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
6244
6245
  			pr_debug("%s: reneging for tsn:%u
  ", __func__, tsn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6246
6247
  			deliver = SCTP_CMD_RENEGE;
  		} else {
bb33381d0   Daniel Borkmann   net: sctp: rework...
6248
6249
6250
  			pr_debug("%s: discard tsn:%u len:%zu, rwnd:%d
  ",
  				 __func__, tsn, datalen, asoc->rwnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6251
6252
6253
6254
6255
  			return SCTP_IERROR_IGNORE_TSN;
  		}
  	}
  
  	/*
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6256
6257
  	 * Also try to renege to limit our memory usage in the event that
  	 * we are under memory pressure
3ab224be6   Hideo Aoki   [NET] CORE: Intro...
6258
  	 * If we can't renege, don't worry about it, the sk_rmem_schedule
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6259
6260
6261
  	 * in sctp_ulpevent_make_rcvmsg will drop the frame if we grow our
  	 * memory usage too much
  	 */
9dde27de3   Xin Long   sctp: implement m...
6262
  	if (sk_under_memory_pressure(sk)) {
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6263
  		if (sctp_tsnmap_has_gap(map) &&
f7010e614   wangweidong   sctp: fix checkpa...
6264
  		    (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
bb33381d0   Daniel Borkmann   net: sctp: rework...
6265
6266
6267
  			pr_debug("%s: under pressure, reneging for tsn:%u
  ",
  				 __func__, tsn);
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6268
  			deliver = SCTP_CMD_RENEGE;
9dde27de3   Xin Long   sctp: implement m...
6269
6270
6271
  		} else {
  			sk_mem_reclaim(sk);
  		}
4d93df0ab   Neil Horman   [SCTP]: Rewrite o...
6272
6273
6274
  	}
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
  	 * Section 3.3.10.9 No User Data (9)
  	 *
  	 * Cause of error
  	 * ---------------
  	 * No User Data:  This error cause is returned to the originator of a
  	 * DATA chunk if a received DATA chunk has no user data.
  	 */
  	if (unlikely(0 == datalen)) {
  		err = sctp_make_abort_no_data(asoc, chunk, tsn);
  		if (err) {
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err));
  		}
  		/* We are going to ABORT, so we might as well stop
  		 * processing the rest of the chunks in the packet.
  		 */
cb3f837ba   wangweidong   sctp: fix checkpa...
6291
  		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
6292
6293
  		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
  				SCTP_ERROR(ECONNABORTED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6294
  		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5be291fe2   Al Viro   [SCTP]: SCTP_CMD_...
6295
  				SCTP_PERR(SCTP_ERROR_NO_DATA));
b01a24078   Eric W. Biederman   sctp: Make the mi...
6296
6297
  		SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
  		SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6298
6299
  		return SCTP_IERROR_NO_DATA;
  	}
9faa730f1   Sridhar Samudrala   [SCTP]: Set chunk...
6300
  	chunk->data_accepted = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6301
6302
6303
  	/* Note: Some chunks may get overcounted (if we drop) or overcounted
  	 * if we renege and the chunk arrives again.
  	 */
196d67593   Michele Baldessari   sctp: Add support...
6304
  	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
b01a24078   Eric W. Biederman   sctp: Make the mi...
6305
  		SCTP_INC_STATS(net, SCTP_MIB_INUNORDERCHUNKS);
196d67593   Michele Baldessari   sctp: Add support...
6306
6307
6308
  		if (chunk->asoc)
  			chunk->asoc->stats.iuodchunks++;
  	} else {
b01a24078   Eric W. Biederman   sctp: Make the mi...
6309
  		SCTP_INC_STATS(net, SCTP_MIB_INORDERCHUNKS);
196d67593   Michele Baldessari   sctp: Add support...
6310
6311
  		if (chunk->asoc)
  			chunk->asoc->stats.iodchunks++;
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
6312
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6313
6314
6315
6316
6317
6318
6319
6320
6321
  
  	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
  	 *
  	 * If an endpoint receive a DATA chunk with an invalid stream
  	 * identifier, it shall acknowledge the reception of the DATA chunk
  	 * following the normal procedure, immediately send an ERROR chunk
  	 * with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
  	 * and discard the DATA chunk.
  	 */
9d4ceaf15   Xin Long   sctp: implement v...
6322
  	if (ntohs(data_hdr->stream) >= asoc->stream.incnt) {
3888e9efc   Vlad Yasevich   sctp: Mark the ts...
6323
6324
  		/* Mark tsn as received even though we drop it */
  		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6325
6326
  		err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
  					 &data_hdr->stream,
6383cfb3e   Vlad Yasevich   sctp: Fix malform...
6327
6328
  					 sizeof(data_hdr->stream),
  					 sizeof(u16));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6329
6330
6331
6332
6333
  		if (err)
  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
  					SCTP_CHUNK(err));
  		return SCTP_IERROR_BAD_STREAM;
  	}
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
6334
6335
6336
6337
6338
6339
6340
  	/* Check to see if the SSN is possible for this TSN.
  	 * The biggest gap we can record is 4K wide.  Since SSNs wrap
  	 * at an unsigned short, there is no way that an SSN can
  	 * wrap and for a valid TSN.  We can simply check if the current
  	 * SSN is smaller then the next expected one.  If it is, it wrapped
  	 * and is invalid.
  	 */
9d4ceaf15   Xin Long   sctp: implement v...
6341
  	if (!asoc->stream.si->validate_data(chunk))
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
6342
  		return SCTP_IERROR_PROTO_VIOLATION;
f1751c57f   Vlad Yasevich   sctp: Catch bogus...
6343

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6344
6345
6346
6347
6348
6349
6350
6351
  	/* Send the data up to the user.  Note:  Schedule  the
  	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
  	 * chunk needs the updated rwnd.
  	 */
  	sctp_add_cmd_sf(commands, deliver, SCTP_CHUNK(chunk));
  
  	return SCTP_IERROR_NO_ERROR;
  }