Blame view

net/sctp/input.c 30.5 KB
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
1
  /* SCTP kernel implementation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
   * Copyright (c) 1999-2000 Cisco, Inc.
   * Copyright (c) 1999-2001 Motorola, Inc.
   * Copyright (c) 2001-2003 International Business Machines, Corp.
   * Copyright (c) 2001 Intel Corp.
   * Copyright (c) 2001 Nokia, Inc.
   * Copyright (c) 2001 La Monte H.P. Yarroll
   *
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
9
   * This file is part of the SCTP kernel implementation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
   *
   * These functions handle all input from the IP layer into SCTP.
   *
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
13
   * This SCTP implementation is free software;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
   * you can redistribute it and/or modify it under the terms of
   * the GNU General Public License as published by
   * the Free Software Foundation; either version 2, or (at your option)
   * any later version.
   *
60c778b25   Vlad Yasevich   [SCTP]: Stop clai...
19
   * This SCTP implementation is distributed in the hope that it
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
   * will be useful, but WITHOUT ANY WARRANTY; without even the implied
   *                 ************************
   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   * See the GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with GNU CC; see the file COPYING.  If not, write to
   * the Free Software Foundation, 59 Temple Place - Suite 330,
   * Boston, MA 02111-1307, USA.
   *
   * Please send any bug reports or fixes you make to the
   * email address(es):
   *    lksctp developers <lksctp-developers@lists.sourceforge.net>
   *
   * Or submit a bug report through the following website:
   *    http://www.sf.net/projects/lksctp
   *
   * Written or modified by:
   *    La Monte H.P. Yarroll <piggy@acm.org>
   *    Karl Knutson <karl@athena.chicago.il.us>
   *    Xingang Guo <xingang.guo@intel.com>
   *    Jon Grimm <jgrimm@us.ibm.com>
   *    Hui Huang <hui.huang@nokia.com>
   *    Daisy Chang <daisyc@us.ibm.com>
   *    Sridhar Samudrala <sri@us.ibm.com>
   *    Ardelle Fan <ardelle.fan@intel.com>
   *
   * Any bugs reported given to us we will try to fix... any fixes shared will
   * be incorporated into the next SCTP release.
   */
  
  #include <linux/types.h>
  #include <linux/list.h> /* For struct list_head */
  #include <linux/socket.h>
  #include <linux/ip.h>
  #include <linux/time.h> /* For struct timeval */
5a0e3ad6a   Tejun Heo   include cleanup: ...
56
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
63
  #include <net/ip.h>
  #include <net/icmp.h>
  #include <net/snmp.h>
  #include <net/sock.h>
  #include <net/xfrm.h>
  #include <net/sctp/sctp.h>
  #include <net/sctp/sm.h>
9ad0977fe   Vlad Yasevich   [SCTP]: Use crc32...
64
  #include <net/sctp/checksum.h>
dcfc23cac   Pavel Emelyanov   mib: add struct n...
65
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
73
74
75
76
77
  
  /* Forward declarations for internal helpers. */
  static int sctp_rcv_ootb(struct sk_buff *);
  static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
  				      const union sctp_addr *laddr,
  				      const union sctp_addr *paddr,
  				      struct sctp_transport **transportp);
  static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
  static struct sctp_association *__sctp_lookup_association(
  					const union sctp_addr *local,
  					const union sctp_addr *peer,
  					struct sctp_transport **pt);
50b1a782f   Zhu Yi   sctp: use limited...
78
  static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
79

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
  
  /* Calculate the SCTP checksum of an SCTP packet.  */
  static inline int sctp_rcv_checksum(struct sk_buff *skb)
  {
2c0fd387b   Arnaldo Carvalho de Melo   [SCTP]: Introduce...
84
  	struct sctphdr *sh = sctp_hdr(skb);
4458f04c0   Vlad Yasevich   sctp: Clean up sc...
85
  	__le32 cmp = sh->checksum;
1b003be39   David S. Miller   sctp: Use frag li...
86
  	struct sk_buff *list;
4458f04c0   Vlad Yasevich   sctp: Clean up sc...
87
88
  	__le32 val;
  	__u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89

1b003be39   David S. Miller   sctp: Use frag li...
90
  	skb_walk_frags(skb, list)
4458f04c0   Vlad Yasevich   sctp: Clean up sc...
91
92
  		tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
  					tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93

4458f04c0   Vlad Yasevich   sctp: Clean up sc...
94
  	val = sctp_end_cksum(tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
98
99
100
101
102
  
  	if (val != cmp) {
  		/* CRC failure, dump it. */
  		SCTP_INC_STATS_BH(SCTP_MIB_CHECKSUMERRORS);
  		return -1;
  	}
  	return 0;
  }
79af02c25   David S. Miller   [SCTP]: Use struc...
103
104
105
  struct sctp_input_cb {
  	union {
  		struct inet_skb_parm	h4;
dfd56b8b3   Eric Dumazet   net: use IS_ENABL...
106
  #if IS_ENABLED(CONFIG_IPV6)
79af02c25   David S. Miller   [SCTP]: Use struc...
107
108
109
110
111
112
  		struct inet6_skb_parm	h6;
  #endif
  	} header;
  	struct sctp_chunk *chunk;
  };
  #define SCTP_INPUT_CB(__skb)	((struct sctp_input_cb *)&((__skb)->cb[0]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  /*
   * This is the routine which IP calls when receiving an SCTP packet.
   */
  int sctp_rcv(struct sk_buff *skb)
  {
  	struct sock *sk;
  	struct sctp_association *asoc;
  	struct sctp_endpoint *ep = NULL;
  	struct sctp_ep_common *rcvr;
  	struct sctp_transport *transport = NULL;
  	struct sctp_chunk *chunk;
  	struct sctphdr *sh;
  	union sctp_addr src;
  	union sctp_addr dest;
  	int family;
  	struct sctp_af *af;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
  
  	if (skb->pkt_type!=PACKET_HOST)
  		goto discard_it;
  
  	SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS);
28cd77527   Herbert Xu   [SCTP]: Always li...
134
135
  	if (skb_linearize(skb))
  		goto discard_it;
2c0fd387b   Arnaldo Carvalho de Melo   [SCTP]: Introduce...
136
  	sh = sctp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
  
  	/* Pull up the IP and SCTP headers. */
ea2ae17d6   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
139
  	__skb_pull(skb, skb_transport_offset(skb));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
  	if (skb->len < sizeof(struct sctphdr))
  		goto discard_it;
06e868066   Lucas Nussbaum   sctp: Allow to di...
142
143
  	if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) &&
  		  sctp_rcv_checksum(skb) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
148
149
150
  		goto discard_it;
  
  	skb_pull(skb, sizeof(struct sctphdr));
  
  	/* Make sure we at least have chunk headers worth of data left. */
  	if (skb->len < sizeof(struct sctp_chunkhdr))
  		goto discard_it;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
151
  	family = ipver2af(ip_hdr(skb)->version);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  	af = sctp_get_af_specific(family);
  	if (unlikely(!af))
  		goto discard_it;
  
  	/* Initialize local addresses for lookups. */
  	af->from_skb(&src, skb, 1);
  	af->from_skb(&dest, skb, 0);
  
  	/* If the packet is to or from a non-unicast address,
  	 * silently discard the packet.
  	 *
  	 * This is not clearly defined in the RFC except in section
  	 * 8.4 - OOTB handling.  However, based on the book "Stream Control
  	 * Transmission Protocol" 2.1, "It is important to note that the
  	 * IP address of an SCTP transport address must be a routable
  	 * unicast address.  In other words, IP multicast addresses and
  	 * IP broadcast addresses cannot be used in an SCTP transport
  	 * address."
  	 */
5636bef73   Vlad Yasevich   [SCTP]: Reject sc...
171
172
  	if (!af->addr_valid(&src, NULL, skb) ||
  	    !af->addr_valid(&dest, NULL, skb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  		goto discard_it;
d55c41b11   Al Viro   [SCTP]: Switch ->...
174
  	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
1c7d1fc14   Al Viro   [SCTP]: Switch sc...
175

0fd9a65a7   Neil Horman   [SCTP] Support SO...
176
  	if (!asoc)
d55c41b11   Al Viro   [SCTP]: Switch ->...
177
  		ep = __sctp_rcv_lookup_endpoint(&dest);
0fd9a65a7   Neil Horman   [SCTP] Support SO...
178
179
180
181
182
183
184
185
186
187
188
  
  	/* Retrieve the common input handling substructure. */
  	rcvr = asoc ? &asoc->base : &ep->base;
  	sk = rcvr->sk;
  
  	/*
  	 * If a frame arrives on an interface and the receiving socket is
  	 * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB
  	 */
  	if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
  	{
0fd9a65a7   Neil Horman   [SCTP] Support SO...
189
190
191
192
193
194
195
196
197
198
  		if (asoc) {
  			sctp_association_put(asoc);
  			asoc = NULL;
  		} else {
  			sctp_endpoint_put(ep);
  			ep = NULL;
  		}
  		sk = sctp_get_ctl_sock();
  		ep = sctp_sk(sk)->ep;
  		sctp_endpoint_hold(ep);
0fd9a65a7   Neil Horman   [SCTP] Support SO...
199
200
  		rcvr = &ep->base;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
207
208
209
  	/*
  	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
  	 * An SCTP packet is called an "out of the blue" (OOTB)
  	 * packet if it is correctly formed, i.e., passed the
  	 * receiver's checksum check, but the receiver is not
  	 * able to identify the association to which this
  	 * packet belongs.
  	 */
  	if (!asoc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
214
  		if (sctp_rcv_ootb(skb)) {
  			SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES);
  			goto discard_release;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
  	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
  		goto discard_release;
b59c27010   Patrick McHardy   [NETFILTER]: Keep...
217
  	nf_reset(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218

fda9ef5d6   Dmitry Mishin   [NET]: Fix sk->sk...
219
  	if (sk_filter(sk, skb))
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
220
  		goto discard_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
  
  	/* Create an SCTP packet structure. */
  	chunk = sctp_chunkify(skb, asoc, sk);
2babf9daa   Herbert Xu   [SCTP]: Fix up sc...
224
  	if (!chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  		goto discard_release;
79af02c25   David S. Miller   [SCTP]: Use struc...
226
  	SCTP_INPUT_CB(skb)->chunk = chunk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
231
232
233
234
  	/* Remember what endpoint is to handle this packet. */
  	chunk->rcvr = rcvr;
  
  	/* Remember the SCTP header. */
  	chunk->sctp_hdr = sh;
  
  	/* Set the source and destination addresses of the incoming chunk.  */
d55c41b11   Al Viro   [SCTP]: Switch ->...
235
  	sctp_init_addrs(chunk, &src, &dest);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
240
241
242
243
244
  
  	/* Remember where we came from.  */
  	chunk->transport = transport;
  
  	/* Acquire access to the sock lock. Note: We are safe from other
  	 * bottom halves on this lock, but a user may be in the lock too,
  	 * so check if it is busy.
  	 */
  	sctp_bh_lock_sock(sk);
ae53b5bd7   Vlad Yasevich   sctp: Fix another...
245
246
247
248
249
250
251
252
253
254
255
256
  	if (sk != rcvr->sk) {
  		/* Our cached sk is different from the rcvr->sk.  This is
  		 * because migrate()/accept() may have moved the association
  		 * to a new socket and released all the sockets.  So now we
  		 * are holding a lock on the old socket while the user may
  		 * be doing something with the new socket.  Switch our veiw
  		 * of the current sk.
  		 */
  		sctp_bh_unlock_sock(sk);
  		sk = rcvr->sk;
  		sctp_bh_lock_sock(sk);
  	}
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
257
  	if (sock_owned_by_user(sk)) {
50b1a782f   Zhu Yi   sctp: use limited...
258
259
260
261
262
263
  		if (sctp_add_backlog(sk, skb)) {
  			sctp_bh_unlock_sock(sk);
  			sctp_chunk_free(chunk);
  			skb = NULL; /* sctp_chunk_free already freed the skb */
  			goto discard_release;
  		}
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
264
  		SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
265
266
  	} else {
  		SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ);
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
267
  		sctp_inq_push(&chunk->rcvr->inqueue, chunk);
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
268
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  	sctp_bh_unlock_sock(sk);
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
271
272
273
274
275
276
  
  	/* Release the asoc/ep ref we took in the lookup calls. */
  	if (asoc)
  		sctp_association_put(asoc);
  	else
  		sctp_endpoint_put(ep);
7a48f923b   Sridhar Samudrala   [SCTP]: Fix poten...
277

2babf9daa   Herbert Xu   [SCTP]: Fix up sc...
278
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
  
  discard_it:
ac0b04627   Sridhar Samudrala   [SCTP]: Extend /p...
281
  	SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_DISCARDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
  	kfree_skb(skb);
2babf9daa   Herbert Xu   [SCTP]: Fix up sc...
283
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
  
  discard_release:
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
286
  	/* Release the asoc/ep ref we took in the lookup calls. */
0fd9a65a7   Neil Horman   [SCTP] Support SO...
287
  	if (asoc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		sctp_association_put(asoc);
0fd9a65a7   Neil Horman   [SCTP] Support SO...
289
  	else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
  		sctp_endpoint_put(ep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
293
  
  	goto discard_it;
  }
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
294
295
296
297
  /* Process the backlog queue of the socket.  Every skb on
   * the backlog holds a ref on an association or endpoint.
   * We hold this ref throughout the state machine to make
   * sure that the structure we need is still around.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
   */
  int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
  {
79af02c25   David S. Miller   [SCTP]: Use struc...
301
  	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
302
303
  	struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
  	struct sctp_ep_common *rcvr = NULL;
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
304
  	int backloged = 0;
7a48f923b   Sridhar Samudrala   [SCTP]: Fix poten...
305

d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
306
  	rcvr = chunk->rcvr;
c4d2444e9   Sridhar Samudrala   [SCTP]: Fix coupl...
307

61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  	/* If the rcvr is dead then the association or endpoint
  	 * has been deleted and we can safely drop the chunk
  	 * and refs that we are holding.
  	 */
  	if (rcvr->dead) {
  		sctp_chunk_free(chunk);
  		goto done;
  	}
  
  	if (unlikely(rcvr->sk != sk)) {
  		/* In this case, the association moved from one socket to
  		 * another.  We are currently sitting on the backlog of the
  		 * old socket, so we need to move.
  		 * However, since we are here in the process context we
  		 * need to take make sure that the user doesn't own
  		 * the new socket when we process the packet.
  		 * If the new socket is user-owned, queue the chunk to the
  		 * backlog of the new socket without dropping any refs.
  		 * Otherwise, we can safely push the chunk on the inqueue.
  		 */
  
  		sk = rcvr->sk;
  		sctp_bh_lock_sock(sk);
  
  		if (sock_owned_by_user(sk)) {
a3a858ff1   Zhu Yi   net: backlog func...
333
  			if (sk_add_backlog(sk, skb))
50b1a782f   Zhu Yi   sctp: use limited...
334
335
336
  				sctp_chunk_free(chunk);
  			else
  				backloged = 1;
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  		} else
  			sctp_inq_push(inqueue, chunk);
  
  		sctp_bh_unlock_sock(sk);
  
  		/* If the chunk was backloged again, don't drop refs */
  		if (backloged)
  			return 0;
  	} else {
  		sctp_inq_push(inqueue, chunk);
  	}
  
  done:
  	/* Release the refs we took in sctp_add_backlog */
  	if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
  		sctp_association_put(sctp_assoc(rcvr));
  	else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
  		sctp_endpoint_put(sctp_ep(rcvr));
  	else
  		BUG();
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
357
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
  }
50b1a782f   Zhu Yi   sctp: use limited...
359
  static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
c4d2444e9   Sridhar Samudrala   [SCTP]: Fix coupl...
360
  {
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
361
362
  	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
  	struct sctp_ep_common *rcvr = chunk->rcvr;
50b1a782f   Zhu Yi   sctp: use limited...
363
  	int ret;
c4d2444e9   Sridhar Samudrala   [SCTP]: Fix coupl...
364

a3a858ff1   Zhu Yi   net: backlog func...
365
  	ret = sk_add_backlog(sk, skb);
50b1a782f   Zhu Yi   sctp: use limited...
366
367
368
369
370
371
372
373
374
375
376
377
378
  	if (!ret) {
  		/* Hold the assoc/ep while hanging on the backlog queue.
  		 * This way, we know structures we need will not disappear
  		 * from us
  		 */
  		if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
  			sctp_association_hold(sctp_assoc(rcvr));
  		else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
  			sctp_endpoint_hold(sctp_ep(rcvr));
  		else
  			BUG();
  	}
  	return ret;
61c9fed41   Vladislav Yasevich   [SCTP]: A better ...
379

c4d2444e9   Sridhar Samudrala   [SCTP]: Fix coupl...
380
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
382
383
384
  /* Handle icmp frag needed error. */
  void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
  			   struct sctp_transport *t, __u32 pmtu)
  {
91bd6b1e0   Wei Yongjun   sctp: Drop ICMP p...
385
  	if (!t || (t->pathmtu <= pmtu))
52ccb8e90   Frank Filz   [SCTP]: Update SC...
386
  		return;
8a4794914   Vlad Yasevich   [SCTP] Flag a pmt...
387
388
389
390
391
  	if (sock_owned_by_user(sk)) {
  		asoc->pmtu_pending = 1;
  		t->pmtu_pending = 1;
  		return;
  	}
52ccb8e90   Frank Filz   [SCTP]: Update SC...
392
  	if (t->param_flags & SPP_PMTUD_ENABLE) {
c910b47e1   Vlad Yasevich   [SCTP] Update pmt...
393
394
  		/* Update transports view of the MTU */
  		sctp_transport_update_pmtu(t, pmtu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395

52ccb8e90   Frank Filz   [SCTP]: Update SC...
396
  		/* Update association pmtu. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  		sctp_assoc_sync_pmtu(asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  	}
52ccb8e90   Frank Filz   [SCTP]: Update SC...
399
400
401
402
403
  
  	/* Retransmit with the new pmtu setting.
  	 * Normally, if PMTU discovery is disabled, an ICMP Fragmentation
  	 * Needed will never be sent, but if a message was sent before
  	 * PMTU discovery was disabled that was larger than the PMTU, it
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
404
  	 * would not be fragmented, so it must be re-transmitted fragmented.
52ccb8e90   Frank Filz   [SCTP]: Update SC...
405
406
  	 */
  	sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  }
  
  /*
   * SCTP Implementer's Guide, 2.37 ICMP handling procedures
   *
   * ICMP8) If the ICMP code is a "Unrecognized next header type encountered"
   *        or a "Protocol Unreachable" treat this message as an abort
   *        with the T bit set.
   *
   * This function sends an event to the state machine, which will abort the
   * association.
   *
   */
  void sctp_icmp_proto_unreachable(struct sock *sk,
d808ad9ab   YOSHIFUJI Hideaki   [NET] SCTP: Fix w...
421
422
  			   struct sctp_association *asoc,
  			   struct sctp_transport *t)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  {
0dc47877a   Harvey Harrison   net: replace rema...
424
425
  	SCTP_DEBUG_PRINTK("%s
  ",  __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426

50b5d6ad6   Vlad Yasevich   sctp: Fix a race ...
427
428
429
430
431
432
433
434
435
436
437
438
439
  	if (sock_owned_by_user(sk)) {
  		if (timer_pending(&t->proto_unreach_timer))
  			return;
  		else {
  			if (!mod_timer(&t->proto_unreach_timer,
  						jiffies + (HZ/20)))
  				sctp_association_hold(asoc);
  		}
  			
  	} else {
  		if (timer_pending(&t->proto_unreach_timer) &&
  		    del_timer(&t->proto_unreach_timer))
  			sctp_association_put(asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440

50b5d6ad6   Vlad Yasevich   sctp: Fix a race ...
441
442
443
444
445
  		sctp_do_sm(SCTP_EVENT_T_OTHER,
  			   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
  			   asoc->state, asoc->ep, asoc, t,
  			   GFP_ATOMIC);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
447
448
449
450
  }
  
  /* Common lookup code for icmp/icmpv6 error handler. */
  struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
  			     struct sctphdr *sctphdr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
454
455
456
457
  			     struct sctp_association **app,
  			     struct sctp_transport **tpp)
  {
  	union sctp_addr saddr;
  	union sctp_addr daddr;
  	struct sctp_af *af;
  	struct sock *sk = NULL;
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
458
  	struct sctp_association *asoc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  	struct sctp_transport *transport = NULL;
7115e632f   Wei Yongjun   sctp: Validate In...
460
461
462
  	struct sctp_init_chunk *chunkhdr;
  	__u32 vtag = ntohl(sctphdr->vtag);
  	int len = skb->len - ((void *)sctphdr - (void *)skb->data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463

d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
464
  	*app = NULL; *tpp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
469
470
471
472
473
474
475
476
477
  
  	af = sctp_get_af_specific(family);
  	if (unlikely(!af)) {
  		return NULL;
  	}
  
  	/* Initialize local addresses for lookups. */
  	af->from_skb(&saddr, skb, 1);
  	af->from_skb(&daddr, skb, 0);
  
  	/* Look for an association that matches the incoming ICMP error
  	 * packet.
  	 */
d55c41b11   Al Viro   [SCTP]: Switch ->...
478
  	asoc = __sctp_lookup_association(&saddr, &daddr, &transport);
d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
479
480
  	if (!asoc)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481

d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
482
  	sk = asoc->base.sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483

7115e632f   Wei Yongjun   sctp: Validate In...
484
485
486
487
488
489
490
491
492
493
494
495
496
  	/* RFC 4960, Appendix C. ICMP Handling
  	 *
  	 * ICMP6) An implementation MUST validate that the Verification Tag
  	 * contained in the ICMP message matches the Verification Tag of
  	 * the peer.  If the Verification Tag is not 0 and does NOT
  	 * match, discard the ICMP message.  If it is 0 and the ICMP
  	 * message contains enough bytes to verify that the chunk type is
  	 * an INIT chunk and that the Initiate Tag matches the tag of the
  	 * peer, continue with ICMP7.  If the ICMP message is too short
  	 * or the chunk type or the Initiate Tag does not match, silently
  	 * discard the packet.
  	 */
  	if (vtag == 0) {
ea1107338   Joe Perches   net: Remove casts...
497
  		chunkhdr = (void *)sctphdr + sizeof(struct sctphdr);
7115e632f   Wei Yongjun   sctp: Validate In...
498
499
500
501
502
503
504
  		if (len < sizeof(struct sctphdr) + sizeof(sctp_chunkhdr_t)
  			  + sizeof(__be32) ||
  		    chunkhdr->chunk_hdr.type != SCTP_CID_INIT ||
  		    ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) {
  			goto out;
  		}
  	} else if (vtag != asoc->c.peer_vtag) {
d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
505
506
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
511
512
513
  
  	sctp_bh_lock_sock(sk);
  
  	/* If too many ICMPs get dropped on busy
  	 * servers this needs to be solved differently.
  	 */
  	if (sock_owned_by_user(sk))
de0744af1   Pavel Emelyanov   mib: add net to N...
514
  		NET_INC_STATS_BH(&init_net, LINUX_MIB_LOCKDROPPEDICMPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
518
519
520
  	*app = asoc;
  	*tpp = transport;
  	return sk;
  
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
522
  	if (asoc)
  		sctp_association_put(asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
525
526
  	return NULL;
  }
  
  /* Common cleanup code for icmp/icmpv6 error handler. */
d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
527
  void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
  {
  	sctp_bh_unlock_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
  	if (asoc)
  		sctp_association_put(asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
  }
  
  /*
   * This routine is called by the ICMP module when it gets some
   * sort of error condition.  If err < 0 then the socket should
   * be closed and the error returned to the user.  If err > 0
   * it's just the icmp type << 8 | icmp code.  After adjustment
   * header points to the first 8 bytes of the sctp header.  We need
   * to find the appropriate port.
   *
   * The locking strategy used here is very "optimistic". When
   * someone else accesses the socket the ICMP is just dropped
   * and for some paths there is no check at all.
   * A more general error queue to queue errors for later handling
   * is probably better.
   *
   */
  void sctp_v4_err(struct sk_buff *skb, __u32 info)
  {
b71d1d426   Eric Dumazet   inet: constify ip...
551
  	const struct iphdr *iph = (const struct iphdr *)skb->data;
a27ef749e   Arnaldo Carvalho de Melo   [SCTP]: Eliminate...
552
  	const int ihlen = iph->ihl * 4;
88c7664f1   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
553
554
  	const int type = icmp_hdr(skb)->type;
  	const int code = icmp_hdr(skb)->code;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
  	struct sock *sk;
8de8c8738   Sridhar Samudrala   [SCTP]: Set sk_er...
556
  	struct sctp_association *asoc = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
558
  	struct sctp_transport *transport;
  	struct inet_sock *inet;
2e07fa9cd   Arnaldo Carvalho de Melo   [SK_BUFF]: Use of...
559
  	sk_buff_data_t saveip, savesctp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
  	int err;
a27ef749e   Arnaldo Carvalho de Melo   [SCTP]: Eliminate...
561
  	if (skb->len < ihlen + 8) {
dcfc23cac   Pavel Emelyanov   mib: add struct n...
562
  		ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
566
  		return;
  	}
  
  	/* Fix up skb to look at the embedded net header. */
b0e380b1d   Arnaldo Carvalho de Melo   [SK_BUFF]: unions...
567
568
  	saveip = skb->network_header;
  	savesctp = skb->transport_header;
31c7711b5   Arnaldo Carvalho de Melo   [SK_BUFF]: Some m...
569
  	skb_reset_network_header(skb);
a27ef749e   Arnaldo Carvalho de Melo   [SCTP]: Eliminate...
570
571
  	skb_set_transport_header(skb, ihlen);
  	sk = sctp_err_lookup(AF_INET, skb, sctp_hdr(skb), &asoc, &transport);
2e07fa9cd   Arnaldo Carvalho de Melo   [SK_BUFF]: Use of...
572
  	/* Put back, the original values. */
b0e380b1d   Arnaldo Carvalho de Melo   [SK_BUFF]: unions...
573
574
  	skb->network_header = saveip;
  	skb->transport_header = savesctp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  	if (!sk) {
dcfc23cac   Pavel Emelyanov   mib: add struct n...
576
  		ICMP_INC_STATS_BH(&init_net, ICMP_MIB_INERRORS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  		return;
  	}
  	/* Warning:  The sock lock is held.  Remember to call
  	 * sctp_err_finish!
  	 */
  
  	switch (type) {
  	case ICMP_PARAMETERPROB:
  		err = EPROTO;
  		break;
  	case ICMP_DEST_UNREACH:
  		if (code > NR_ICMP_UNREACH)
  			goto out_unlock;
  
  		/* PMTU discovery (RFC1191) */
  		if (ICMP_FRAG_NEEDED == code) {
  			sctp_icmp_frag_needed(sk, asoc, transport, info);
  			goto out_unlock;
  		}
  		else {
  			if (ICMP_PROT_UNREACH == code) {
d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
598
  				sctp_icmp_proto_unreachable(sk, asoc,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  							    transport);
  				goto out_unlock;
  			}
  		}
  		err = icmp_err_convert[code].errno;
  		break;
  	case ICMP_TIME_EXCEEDED:
  		/* Ignore any time exceeded errors due to fragment reassembly
  		 * timeouts.
  		 */
  		if (ICMP_EXC_FRAGTIME == code)
  			goto out_unlock;
  
  		err = EHOSTUNREACH;
  		break;
  	default:
  		goto out_unlock;
  	}
  
  	inet = inet_sk(sk);
  	if (!sock_owned_by_user(sk) && inet->recverr) {
  		sk->sk_err = err;
  		sk->sk_error_report(sk);
  	} else {  /* Only an error on timeout */
  		sk->sk_err_soft = err;
  	}
  
  out_unlock:
d1ad1ff29   Sridhar Samudrala   [SCTP]: Fix poten...
627
  	sctp_err_finish(sk, asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  }
  
  /*
   * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
   *
   * This function scans all the chunks in the OOTB packet to determine if
   * the packet should be discarded right away.  If a response might be needed
   * for this packet, or, if further processing is possible, the packet will
   * be queued to a proper inqueue for the next phase of handling.
   *
   * Output:
   * Return 0 - If further processing is needed.
   * Return 1 - If the packet can be discarded right away.
   */
046752104   sebastian@breakpoint.cc   sctp: make locall...
642
  static int sctp_rcv_ootb(struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
644
645
  {
  	sctp_chunkhdr_t *ch;
  	__u8 *ch_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
  
  	ch = (sctp_chunkhdr_t *) skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
  
  	/* Scan through all the chunks in the packet.  */
a7d1f1b66   Tsutomu Fujii   [SCTP]: Fix sctp_...
650
651
652
653
654
655
  	do {
  		/* Break out if chunk length is less then minimal. */
  		if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
  			break;
  
  		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
656
  		if (ch_end > skb_tail_pointer(skb))
a7d1f1b66   Tsutomu Fujii   [SCTP]: Fix sctp_...
657
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
661
662
663
664
665
666
667
668
669
670
671
  
  		/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
  		 * receiver MUST silently discard the OOTB packet and take no
  		 * further action.
  		 */
  		if (SCTP_CID_ABORT == ch->type)
  			goto discard;
  
  		/* RFC 8.4, 6) If the packet contains a SHUTDOWN COMPLETE
  		 * chunk, the receiver should silently discard the packet
  		 * and take no further action.
  		 */
  		if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type)
  			goto discard;
3c77f961b   Vlad Yasevich   SCTP: Discard OOT...
672
673
674
675
676
677
678
  		/* RFC 4460, 2.11.2
  		 * This will discard packets with INIT chunk bundled as
  		 * subsequent chunks in the packet.  When INIT is first,
  		 * the normal INIT processing will discard the chunk.
  		 */
  		if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data)
  			goto discard;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
  		ch = (sctp_chunkhdr_t *) ch_end;
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
680
  	} while (ch_end < skb_tail_pointer(skb));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
685
686
687
688
689
690
  
  	return 0;
  
  discard:
  	return 1;
  }
  
  /* Insert endpoint into the hash table.  */
  static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
694
695
696
697
698
699
  	struct sctp_ep_common *epb;
  	struct sctp_hashbucket *head;
  
  	epb = &ep->base;
  
  	epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
  	head = &sctp_ep_hashtable[epb->hashent];
  
  	sctp_write_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
700
  	hlist_add_head(&epb->node, &head->chain);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  	sctp_write_unlock(&head->lock);
  }
  
  /* Add an endpoint to the hash. Local BH-safe. */
  void sctp_hash_endpoint(struct sctp_endpoint *ep)
  {
  	sctp_local_bh_disable();
  	__sctp_hash_endpoint(ep);
  	sctp_local_bh_enable();
  }
  
  /* Remove endpoint from the hash table.  */
  static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
  {
  	struct sctp_hashbucket *head;
  	struct sctp_ep_common *epb;
  
  	epb = &ep->base;
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
719
720
  	if (hlist_unhashed(&epb->node))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
722
723
724
725
  	epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
  
  	head = &sctp_ep_hashtable[epb->hashent];
  
  	sctp_write_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
726
  	__hlist_del(&epb->node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  	sctp_write_unlock(&head->lock);
  }
  
  /* Remove endpoint from the hash.  Local BH-safe. */
  void sctp_unhash_endpoint(struct sctp_endpoint *ep)
  {
  	sctp_local_bh_disable();
  	__sctp_unhash_endpoint(ep);
  	sctp_local_bh_enable();
  }
  
  /* Look up an endpoint. */
  static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
  {
  	struct sctp_hashbucket *head;
  	struct sctp_ep_common *epb;
  	struct sctp_endpoint *ep;
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
744
  	struct hlist_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
  	int hash;
1c7d1fc14   Al Viro   [SCTP]: Switch sc...
746
  	hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
  	head = &sctp_ep_hashtable[hash];
  	read_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
749
  	sctp_for_each_hentry(epb, node, &head->chain) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
753
754
755
  		ep = sctp_ep(epb);
  		if (sctp_endpoint_is_match(ep, laddr))
  			goto hit;
  	}
  
  	ep = sctp_sk((sctp_get_ctl_sock()))->ep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
757
758
  
  hit:
  	sctp_endpoint_hold(ep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
760
761
762
763
764
765
  	read_unlock(&head->lock);
  	return ep;
  }
  
  /* Insert association into the hash table.  */
  static void __sctp_hash_established(struct sctp_association *asoc)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
767
768
769
770
771
772
773
774
775
776
  	struct sctp_ep_common *epb;
  	struct sctp_hashbucket *head;
  
  	epb = &asoc->base;
  
  	/* Calculate which chain this entry will belong to. */
  	epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port, asoc->peer.port);
  
  	head = &sctp_assoc_hashtable[epb->hashent];
  
  	sctp_write_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
777
  	hlist_add_head(&epb->node, &head->chain);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
780
781
782
783
  	sctp_write_unlock(&head->lock);
  }
  
  /* Add an association to the hash. Local BH-safe. */
  void sctp_hash_established(struct sctp_association *asoc)
  {
de76e695a   Vlad Yasevich   [SCTP]: Remove te...
784
785
  	if (asoc->temp)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
  	sctp_local_bh_disable();
  	__sctp_hash_established(asoc);
  	sctp_local_bh_enable();
  }
  
  /* Remove association from the hash table.  */
  static void __sctp_unhash_established(struct sctp_association *asoc)
  {
  	struct sctp_hashbucket *head;
  	struct sctp_ep_common *epb;
  
  	epb = &asoc->base;
  
  	epb->hashent = sctp_assoc_hashfn(epb->bind_addr.port,
  					 asoc->peer.port);
  
  	head = &sctp_assoc_hashtable[epb->hashent];
  
  	sctp_write_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
805
  	__hlist_del(&epb->node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
807
808
809
810
811
  	sctp_write_unlock(&head->lock);
  }
  
  /* Remove association from the hash table.  Local BH-safe. */
  void sctp_unhash_established(struct sctp_association *asoc)
  {
de76e695a   Vlad Yasevich   [SCTP]: Remove te...
812
813
  	if (asoc->temp)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
  	sctp_local_bh_disable();
  	__sctp_unhash_established(asoc);
  	sctp_local_bh_enable();
  }
  
  /* Look up an association. */
  static struct sctp_association *__sctp_lookup_association(
  					const union sctp_addr *local,
  					const union sctp_addr *peer,
  					struct sctp_transport **pt)
  {
  	struct sctp_hashbucket *head;
  	struct sctp_ep_common *epb;
  	struct sctp_association *asoc;
  	struct sctp_transport *transport;
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
829
  	struct hlist_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830
831
832
833
834
  	int hash;
  
  	/* Optimize here for direct hit, only listening connections can
  	 * have wildcards anyways.
  	 */
e2fccedb0   Al Viro   [SCTP]: Switch sc...
835
  	hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
  	head = &sctp_assoc_hashtable[hash];
  	read_lock(&head->lock);
d970dbf84   Vlad Yasevich   SCTP: Convert cus...
838
  	sctp_for_each_hentry(epb, node, &head->chain) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
840
841
842
843
844
845
846
847
848
849
850
851
  		asoc = sctp_assoc(epb);
  		transport = sctp_assoc_is_match(asoc, local, peer);
  		if (transport)
  			goto hit;
  	}
  
  	read_unlock(&head->lock);
  
  	return NULL;
  
  hit:
  	*pt = transport;
  	sctp_association_hold(asoc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
  	read_unlock(&head->lock);
  	return asoc;
  }
  
  /* Look up an association. BH-safe. */
  SCTP_STATIC
  struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr,
  						 const union sctp_addr *paddr,
  					    struct sctp_transport **transportp)
  {
  	struct sctp_association *asoc;
  
  	sctp_local_bh_disable();
  	asoc = __sctp_lookup_association(laddr, paddr, transportp);
  	sctp_local_bh_enable();
  
  	return asoc;
  }
  
  /* Is there an association matching the given local and peer addresses? */
  int sctp_has_association(const union sctp_addr *laddr,
  			 const union sctp_addr *paddr)
  {
  	struct sctp_association *asoc;
  	struct sctp_transport *transport;
6c7be55ca   Al Viro   [SCTP]: sctp_has_...
877
  	if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  		sctp_association_put(asoc);
  		return 1;
  	}
  
  	return 0;
  }
  
  /*
   * SCTP Implementors Guide, 2.18 Handling of address
   * parameters within the INIT or INIT-ACK.
   *
   * D) When searching for a matching TCB upon reception of an INIT
   *    or INIT-ACK chunk the receiver SHOULD use not only the
   *    source address of the packet (containing the INIT or
   *    INIT-ACK) but the receiver SHOULD also use all valid
   *    address parameters contained within the chunk.
   *
   * 2.18.3 Solution description
   *
   * This new text clearly specifies to an implementor the need
   * to look within the INIT or INIT-ACK. Any implementation that
   * does not do this, may not be able to establish associations
   * in certain circumstances.
   *
   */
  static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
  	const union sctp_addr *laddr, struct sctp_transport **transportp)
  {
  	struct sctp_association *asoc;
  	union sctp_addr addr;
  	union sctp_addr *paddr = &addr;
2c0fd387b   Arnaldo Carvalho de Melo   [SCTP]: Introduce...
909
  	struct sctphdr *sh = sctp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
910
911
912
913
  	union sctp_params params;
  	sctp_init_chunk_t *init;
  	struct sctp_transport *transport;
  	struct sctp_af *af;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
  	/*
  	 * This code will NOT touch anything inside the chunk--it is
  	 * strictly READ-ONLY.
  	 *
  	 * RFC 2960 3  SCTP packet Format
  	 *
  	 * Multiple chunks can be bundled into one SCTP packet up to
  	 * the MTU size, except for the INIT, INIT ACK, and SHUTDOWN
  	 * COMPLETE chunks.  These chunks MUST NOT be bundled with any
  	 * other chunk in a packet.  See Section 6.10 for more details
  	 * on chunk bundling.
  	 */
  
  	/* Find the start of the TLVs and the end of the chunk.  This is
  	 * the region we search for address parameters.
  	 */
  	init = (sctp_init_chunk_t *)skb->data;
  
  	/* Walk the parameters looking for embedded addresses. */
  	sctp_walk_params(params, init, init_hdr.params) {
  
  		/* Note: Ignoring hostname addresses. */
  		af = sctp_get_af_specific(param_type2af(params.p->type));
  		if (!af)
  			continue;
dd86d136f   Al Viro   [SCTP]: Switch ->...
939
  		af->from_addr_param(paddr, params.addr, sh->source, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940

dd86d136f   Al Viro   [SCTP]: Switch ->...
941
  		asoc = __sctp_lookup_association(laddr, paddr, &transport);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
943
944
945
946
947
  		if (asoc)
  			return asoc;
  	}
  
  	return NULL;
  }
df2185771   Vlad Yasevich   [SCTP]: Update as...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  /* ADD-IP, Section 5.2
   * When an endpoint receives an ASCONF Chunk from the remote peer
   * special procedures may be needed to identify the association the
   * ASCONF Chunk is associated with. To properly find the association
   * the following procedures SHOULD be followed:
   *
   * D2) If the association is not found, use the address found in the
   * Address Parameter TLV combined with the port number found in the
   * SCTP common header. If found proceed to rule D4.
   *
   * D2-ext) If more than one ASCONF Chunks are packed together, use the
   * address found in the ASCONF Address Parameter TLV of each of the
   * subsequent ASCONF Chunks. If found, proceed to rule D4.
   */
  static struct sctp_association *__sctp_rcv_asconf_lookup(
  					sctp_chunkhdr_t *ch,
  					const union sctp_addr *laddr,
bc92dd194   Al Viro   [SCTP]: fix misan...
965
  					__be16 peer_port,
df2185771   Vlad Yasevich   [SCTP]: Update as...
966
967
968
969
970
971
972
973
974
  					struct sctp_transport **transportp)
  {
  	sctp_addip_chunk_t *asconf = (struct sctp_addip_chunk *)ch;
  	struct sctp_af *af;
  	union sctp_addr_param *param;
  	union sctp_addr paddr;
  
  	/* Skip over the ADDIP header and find the Address parameter */
  	param = (union sctp_addr_param *)(asconf + 1);
6a435732a   Shan Wei   sctp: use common ...
975
  	af = sctp_get_af_specific(param_type2af(param->p.type));
df2185771   Vlad Yasevich   [SCTP]: Update as...
976
977
978
979
980
981
982
  	if (unlikely(!af))
  		return NULL;
  
  	af->from_addr_param(&paddr, param, peer_port, 0);
  
  	return __sctp_lookup_association(laddr, &paddr, transportp);
  }
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
983
984
985
986
987
988
989
  /* SCTP-AUTH, Section 6.3:
  *    If the receiver does not find a STCB for a packet containing an AUTH
  *    chunk as the first chunk and not a COOKIE-ECHO chunk as the second
  *    chunk, it MUST use the chunks after the AUTH chunk to look up an existing
  *    association.
  *
  * This means that any chunks that can help us identify the association need
25985edce   Lucas De Marchi   Fix common misspe...
990
  * to be looked at to find this association.
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
991
  */
df2185771   Vlad Yasevich   [SCTP]: Update as...
992
  static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
993
994
995
  				      const union sctp_addr *laddr,
  				      struct sctp_transport **transportp)
  {
df2185771   Vlad Yasevich   [SCTP]: Update as...
996
997
998
999
1000
1001
1002
1003
  	struct sctp_association *asoc = NULL;
  	sctp_chunkhdr_t *ch;
  	int have_auth = 0;
  	unsigned int chunk_num = 1;
  	__u8 *ch_end;
  
  	/* Walk through the chunks looking for AUTH or ASCONF chunks
  	 * to help us find the association.
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1004
  	 */
df2185771   Vlad Yasevich   [SCTP]: Update as...
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  	ch = (sctp_chunkhdr_t *) skb->data;
  	do {
  		/* Break out if chunk length is less then minimal. */
  		if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
  			break;
  
  		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
  		if (ch_end > skb_tail_pointer(skb))
  			break;
  
  		switch(ch->type) {
  		    case SCTP_CID_AUTH:
  			    have_auth = chunk_num;
  			    break;
  
  		    case SCTP_CID_COOKIE_ECHO:
  			    /* If a packet arrives containing an AUTH chunk as
  			     * a first chunk, a COOKIE-ECHO chunk as the second
  			     * chunk, and possibly more chunks after them, and
  			     * the receiver does not have an STCB for that
  			     * packet, then authentication is based on
  			     * the contents of the COOKIE- ECHO chunk.
  			     */
  			    if (have_auth == 1 && chunk_num == 2)
  				    return NULL;
  			    break;
  
  		    case SCTP_CID_ASCONF:
  			    if (have_auth || sctp_addip_noauth)
  				    asoc = __sctp_rcv_asconf_lookup(ch, laddr,
  							sctp_hdr(skb)->source,
  							transportp);
  		    default:
  			    break;
  		}
  
  		if (asoc)
  			break;
  
  		ch = (sctp_chunkhdr_t *) ch_end;
  		chunk_num++;
  	} while (ch_end < skb_tail_pointer(skb));
  
  	return asoc;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1049
1050
1051
1052
1053
1054
1055
1056
1057
  }
  
  /*
   * There are circumstances when we need to look inside the SCTP packet
   * for information to help us find the association.   Examples
   * include looking inside of INIT/INIT-ACK chunks or after the AUTH
   * chunks.
   */
  static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1058
1059
1060
1061
1062
1063
  				      const union sctp_addr *laddr,
  				      struct sctp_transport **transportp)
  {
  	sctp_chunkhdr_t *ch;
  
  	ch = (sctp_chunkhdr_t *) skb->data;
df2185771   Vlad Yasevich   [SCTP]: Update as...
1064
1065
1066
1067
1068
1069
1070
  	/* The code below will attempt to walk the chunk and extract
  	 * parameter information.  Before we do that, we need to verify
  	 * that the chunk length doesn't cause overflow.  Otherwise, we'll
  	 * walk off the end.
  	 */
  	if (WORD_ROUND(ntohs(ch->length)) > skb->len)
  		return NULL;
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1071
1072
1073
1074
1075
1076
  	/* If this is INIT/INIT-ACK look inside the chunk too. */
  	switch (ch->type) {
  	case SCTP_CID_INIT:
  	case SCTP_CID_INIT_ACK:
  		return __sctp_rcv_init_lookup(skb, laddr, transportp);
  		break;
df2185771   Vlad Yasevich   [SCTP]: Update as...
1077
1078
  	default:
  		return __sctp_rcv_walk_lookup(skb, laddr, transportp);
bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1079
1080
  		break;
  	}
df2185771   Vlad Yasevich   [SCTP]: Update as...
1081

bbd0d5980   Vlad Yasevich   [SCTP]: Implement...
1082
1083
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
  /* Lookup an association for an inbound skb. */
  static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
  				      const union sctp_addr *paddr,
  				      const union sctp_addr *laddr,
  				      struct sctp_transport **transportp)
  {
  	struct sctp_association *asoc;
  
  	asoc = __sctp_lookup_association(laddr, paddr, transportp);
  
  	/* Further lookup for INIT/INIT-ACK packets.
  	 * SCTP Implementors Guide, 2.18 Handling of address
  	 * parameters within the INIT or INIT-ACK.
  	 */
  	if (!asoc)
df2185771   Vlad Yasevich   [SCTP]: Update as...
1099
  		asoc = __sctp_rcv_lookup_harder(skb, laddr, transportp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
1101
1102
  
  	return asoc;
  }