input.c 31.5 KB
Newer Older
1
/* SCTP kernel implementation
Linus Torvalds's avatar
Linus Torvalds committed
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
 *
9
 * This file is part of the SCTP kernel implementation
Linus Torvalds's avatar
Linus Torvalds committed
10
11
12
 *
 * These functions handle all input from the IP layer into SCTP.
 *
13
 * This SCTP implementation is free software;
Linus Torvalds's avatar
Linus Torvalds committed
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.
 *
19
 * This SCTP implementation is distributed in the hope that it
Linus Torvalds's avatar
Linus Torvalds committed
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 */
56
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
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>
64
#include <net/sctp/checksum.h>
65
#include <net/net_namespace.h>
Linus Torvalds's avatar
Linus Torvalds committed
66
67
68

/* Forward declarations for internal helpers. */
static int sctp_rcv_ootb(struct sk_buff *);
69
70
static struct sctp_association *__sctp_rcv_lookup(struct net *net,
				      struct sk_buff *skb,
Linus Torvalds's avatar
Linus Torvalds committed
71
				      const union sctp_addr *paddr,
72
				      const union sctp_addr *laddr,
Linus Torvalds's avatar
Linus Torvalds committed
73
				      struct sctp_transport **transportp);
74
75
static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
						const union sctp_addr *laddr);
Linus Torvalds's avatar
Linus Torvalds committed
76
static struct sctp_association *__sctp_lookup_association(
77
					struct net *net,
Linus Torvalds's avatar
Linus Torvalds committed
78
79
80
81
					const union sctp_addr *local,
					const union sctp_addr *peer,
					struct sctp_transport **pt);

Zhu Yi's avatar
Zhu Yi committed
82
static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
83

Linus Torvalds's avatar
Linus Torvalds committed
84
85

/* Calculate the SCTP checksum of an SCTP packet.  */
86
static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb)
Linus Torvalds's avatar
Linus Torvalds committed
87
{
88
	struct sctphdr *sh = sctp_hdr(skb);
89
	__le32 cmp = sh->checksum;
90
	struct sk_buff *list;
91
92
	__le32 val;
	__u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
Linus Torvalds's avatar
Linus Torvalds committed
93

94
	skb_walk_frags(skb, list)
95
96
		tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
					tmp);
Linus Torvalds's avatar
Linus Torvalds committed
97

98
	val = sctp_end_cksum(tmp);
Linus Torvalds's avatar
Linus Torvalds committed
99
100
101

	if (val != cmp) {
		/* CRC failure, dump it. */
102
		SCTP_INC_STATS_BH(net, SCTP_MIB_CHECKSUMERRORS);
Linus Torvalds's avatar
Linus Torvalds committed
103
104
105
106
107
		return -1;
	}
	return 0;
}

108
109
110
struct sctp_input_cb {
	union {
		struct inet_skb_parm	h4;
111
#if IS_ENABLED(CONFIG_IPV6)
112
113
114
115
116
117
118
		struct inet6_skb_parm	h6;
#endif
	} header;
	struct sctp_chunk *chunk;
};
#define SCTP_INPUT_CB(__skb)	((struct sctp_input_cb *)&((__skb)->cb[0]))

Linus Torvalds's avatar
Linus Torvalds committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * 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;
135
	struct net *net = dev_net(skb->dev);
Linus Torvalds's avatar
Linus Torvalds committed
136
137
138
139

	if (skb->pkt_type!=PACKET_HOST)
		goto discard_it;

140
	SCTP_INC_STATS_BH(net, SCTP_MIB_INSCTPPACKS);
Linus Torvalds's avatar
Linus Torvalds committed
141

142
143
144
	if (skb_linearize(skb))
		goto discard_it;

145
	sh = sctp_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
146
147

	/* Pull up the IP and SCTP headers. */
148
	__skb_pull(skb, skb_transport_offset(skb));
Linus Torvalds's avatar
Linus Torvalds committed
149
150
	if (skb->len < sizeof(struct sctphdr))
		goto discard_it;
151
	if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) &&
152
		  sctp_rcv_checksum(net, skb) < 0)
Linus Torvalds's avatar
Linus Torvalds committed
153
154
155
156
157
158
159
160
		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;

161
	family = ipver2af(ip_hdr(skb)->version);
Linus Torvalds's avatar
Linus Torvalds committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
	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."
	 */
181
182
	if (!af->addr_valid(&src, NULL, skb) ||
	    !af->addr_valid(&dest, NULL, skb))
Linus Torvalds's avatar
Linus Torvalds committed
183
184
		goto discard_it;

185
	asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport);
186

187
	if (!asoc)
188
		ep = __sctp_rcv_lookup_endpoint(net, &dest);
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

	/* 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)))
	{
		if (asoc) {
			sctp_association_put(asoc);
			asoc = NULL;
		} else {
			sctp_endpoint_put(ep);
			ep = NULL;
		}
207
		sk = net->sctp.ctl_sock;
208
209
210
211
212
		ep = sctp_sk(sk)->ep;
		sctp_endpoint_hold(ep);
		rcvr = &ep->base;
	}

Linus Torvalds's avatar
Linus Torvalds committed
213
214
215
216
217
218
219
220
221
222
	/*
	 * 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) {
		if (sctp_rcv_ootb(skb)) {
223
			SCTP_INC_STATS_BH(net, SCTP_MIB_OUTOFBLUES);
Linus Torvalds's avatar
Linus Torvalds committed
224
225
226
227
228
229
			goto discard_release;
		}
	}

	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
		goto discard_release;
230
	nf_reset(skb);
Linus Torvalds's avatar
Linus Torvalds committed
231

232
	if (sk_filter(sk, skb))
233
		goto discard_release;
Linus Torvalds's avatar
Linus Torvalds committed
234
235
236

	/* Create an SCTP packet structure. */
	chunk = sctp_chunkify(skb, asoc, sk);
237
	if (!chunk)
Linus Torvalds's avatar
Linus Torvalds committed
238
		goto discard_release;
239
	SCTP_INPUT_CB(skb)->chunk = chunk;
Linus Torvalds's avatar
Linus Torvalds committed
240
241
242
243
244
245
246
247

	/* 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.  */
248
	sctp_init_addrs(chunk, &src, &dest);
Linus Torvalds's avatar
Linus Torvalds committed
249
250
251
252
253
254
255
256
257
258

	/* 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);

259
260
261
262
263
264
265
266
267
268
269
270
271
	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);
	}

272
	if (sock_owned_by_user(sk)) {
Zhu Yi's avatar
Zhu Yi committed
273
274
275
276
277
278
		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;
		}
279
		SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_BACKLOG);
280
	} else {
281
		SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_SOFTIRQ);
282
		sctp_inq_push(&chunk->rcvr->inqueue, chunk);
283
	}
Linus Torvalds's avatar
Linus Torvalds committed
284
285

	sctp_bh_unlock_sock(sk);
286
287
288
289
290
291

	/* Release the asoc/ep ref we took in the lookup calls. */
	if (asoc)
		sctp_association_put(asoc);
	else
		sctp_endpoint_put(ep);
292

293
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
294
295

discard_it:
296
	SCTP_INC_STATS_BH(net, SCTP_MIB_IN_PKT_DISCARDS);
Linus Torvalds's avatar
Linus Torvalds committed
297
	kfree_skb(skb);
298
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
299
300

discard_release:
301
	/* Release the asoc/ep ref we took in the lookup calls. */
302
	if (asoc)
Linus Torvalds's avatar
Linus Torvalds committed
303
		sctp_association_put(asoc);
304
	else
Linus Torvalds's avatar
Linus Torvalds committed
305
306
307
308
309
		sctp_endpoint_put(ep);

	goto discard_it;
}

310
311
312
313
/* 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.
Linus Torvalds's avatar
Linus Torvalds committed
314
315
316
 */
int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
317
	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
318
319
	struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
	struct sctp_ep_common *rcvr = NULL;
320
	int backloged = 0;
321

322
	rcvr = chunk->rcvr;
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
	/* 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)) {
349
			if (sk_add_backlog(sk, skb, sk->sk_rcvbuf))
Zhu Yi's avatar
Zhu Yi committed
350
351
352
				sctp_chunk_free(chunk);
			else
				backloged = 1;
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
		} 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();

374
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
375
376
}

Zhu Yi's avatar
Zhu Yi committed
377
static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
378
{
379
380
	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
	struct sctp_ep_common *rcvr = chunk->rcvr;
Zhu Yi's avatar
Zhu Yi committed
381
	int ret;
382

383
	ret = sk_add_backlog(sk, skb, sk->sk_rcvbuf);
Zhu Yi's avatar
Zhu Yi committed
384
385
386
387
388
389
390
391
392
393
394
395
396
	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;
397

398
399
}

Linus Torvalds's avatar
Linus Torvalds committed
400
401
402
403
/* Handle icmp frag needed error. */
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
			   struct sctp_transport *t, __u32 pmtu)
{
404
	if (!t || (t->pathmtu <= pmtu))
405
406
		return;

407
408
409
410
411
412
	if (sock_owned_by_user(sk)) {
		asoc->pmtu_pending = 1;
		t->pmtu_pending = 1;
		return;
	}

413
	if (t->param_flags & SPP_PMTUD_ENABLE) {
414
		/* Update transports view of the MTU */
415
		sctp_transport_update_pmtu(sk, t, pmtu);
Linus Torvalds's avatar
Linus Torvalds committed
416

417
		/* Update association pmtu. */
418
		sctp_assoc_sync_pmtu(sk, asoc);
Linus Torvalds's avatar
Linus Torvalds committed
419
	}
420
421
422
423
424

	/* 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
425
	 * would not be fragmented, so it must be re-transmitted fragmented.
426
427
	 */
	sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
Linus Torvalds's avatar
Linus Torvalds committed
428
429
}

430
431
void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t,
			struct sk_buff *skb)
432
433
434
435
436
437
{
	struct dst_entry *dst;

	if (!t)
		return;
	dst = sctp_transport_dst_check(t);
438
	if (dst)
439
		dst->ops->redirect(dst, sk, skb);
440
441
}

Linus Torvalds's avatar
Linus Torvalds committed
442
443
444
445
446
447
448
449
450
451
452
453
/*
 * 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,
454
455
			   struct sctp_association *asoc,
			   struct sctp_transport *t)
Linus Torvalds's avatar
Linus Torvalds committed
456
{
457
	SCTP_DEBUG_PRINTK("%s\n",  __func__);
Linus Torvalds's avatar
Linus Torvalds committed
458

459
460
461
462
463
464
465
466
467
468
	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 {
469
470
		struct net *net = sock_net(sk);

471
		if (del_timer(&t->proto_unreach_timer))
472
			sctp_association_put(asoc);
Linus Torvalds's avatar
Linus Torvalds committed
473

474
		sctp_do_sm(net, SCTP_EVENT_T_OTHER,
475
476
477
478
			   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
			   asoc->state, asoc->ep, asoc, t,
			   GFP_ATOMIC);
	}
Linus Torvalds's avatar
Linus Torvalds committed
479
480
481
}

/* Common lookup code for icmp/icmpv6 error handler. */
482
struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb,
Linus Torvalds's avatar
Linus Torvalds committed
483
484
485
486
487
488
489
490
			     struct sctphdr *sctphdr,
			     struct sctp_association **app,
			     struct sctp_transport **tpp)
{
	union sctp_addr saddr;
	union sctp_addr daddr;
	struct sctp_af *af;
	struct sock *sk = NULL;
491
	struct sctp_association *asoc;
Linus Torvalds's avatar
Linus Torvalds committed
492
	struct sctp_transport *transport = NULL;
493
494
495
	struct sctp_init_chunk *chunkhdr;
	__u32 vtag = ntohl(sctphdr->vtag);
	int len = skb->len - ((void *)sctphdr - (void *)skb->data);
Linus Torvalds's avatar
Linus Torvalds committed
496

497
	*app = NULL; *tpp = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
498
499
500
501
502
503
504
505
506
507
508
509
510

	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.
	 */
511
	asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport);
512
513
	if (!asoc)
		return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
514

515
	sk = asoc->base.sk;
Linus Torvalds's avatar
Linus Torvalds committed
516

517
518
519
520
521
522
523
524
525
526
527
528
529
	/* 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) {
Joe Perches's avatar
Joe Perches committed
530
		chunkhdr = (void *)sctphdr + sizeof(struct sctphdr);
531
532
533
534
535
536
537
		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) {
538
539
		goto out;
	}
Linus Torvalds's avatar
Linus Torvalds committed
540
541
542
543
544
545
546

	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))
547
		NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
Linus Torvalds's avatar
Linus Torvalds committed
548
549
550
551
552
553
554
555
556
557
558
559

	*app = asoc;
	*tpp = transport;
	return sk;

out:
	if (asoc)
		sctp_association_put(asoc);
	return NULL;
}

/* Common cleanup code for icmp/icmpv6 error handler. */
560
void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
Linus Torvalds's avatar
Linus Torvalds committed
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
{
	sctp_bh_unlock_sock(sk);
	if (asoc)
		sctp_association_put(asoc);
}

/*
 * 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)
{
584
	const struct iphdr *iph = (const struct iphdr *)skb->data;
585
	const int ihlen = iph->ihl * 4;
586
587
	const int type = icmp_hdr(skb)->type;
	const int code = icmp_hdr(skb)->code;
Linus Torvalds's avatar
Linus Torvalds committed
588
	struct sock *sk;
589
	struct sctp_association *asoc = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
590
591
	struct sctp_transport *transport;
	struct inet_sock *inet;
592
	__u16 saveip, savesctp;
Linus Torvalds's avatar
Linus Torvalds committed
593
	int err;
594
	struct net *net = dev_net(skb->dev);
Linus Torvalds's avatar
Linus Torvalds committed
595

596
	if (skb->len < ihlen + 8) {
597
		ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
Linus Torvalds's avatar
Linus Torvalds committed
598
599
600
601
		return;
	}

	/* Fix up skb to look at the embedded net header. */
602
603
	saveip = skb->network_header;
	savesctp = skb->transport_header;
604
	skb_reset_network_header(skb);
605
	skb_set_transport_header(skb, ihlen);
606
	sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport);
607
	/* Put back, the original values. */
608
609
	skb->network_header = saveip;
	skb->transport_header = savesctp;
Linus Torvalds's avatar
Linus Torvalds committed
610
	if (!sk) {
611
		ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
Linus Torvalds's avatar
Linus Torvalds committed
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
		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) {
633
				sctp_icmp_proto_unreachable(sk, asoc,
Linus Torvalds's avatar
Linus Torvalds committed
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
							    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;
649
650
651
652
	case ICMP_REDIRECT:
		sctp_icmp_redirect(sk, transport, skb);
		err = 0;
		break;
Linus Torvalds's avatar
Linus Torvalds committed
653
654
655
656
657
658
659
660
661
662
663
664
665
	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:
666
	sctp_err_finish(sk, asoc);
Linus Torvalds's avatar
Linus Torvalds committed
667
668
669
670
671
672
673
674
675
676
677
678
679
680
}

/*
 * 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.
 */
681
static int sctp_rcv_ootb(struct sk_buff *skb)
Linus Torvalds's avatar
Linus Torvalds committed
682
683
684
685
686
687
688
{
	sctp_chunkhdr_t *ch;
	__u8 *ch_end;

	ch = (sctp_chunkhdr_t *) skb->data;

	/* Scan through all the chunks in the packet.  */
689
690
691
692
693
694
	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));
695
		if (ch_end > skb_tail_pointer(skb))
696
			break;
Linus Torvalds's avatar
Linus Torvalds committed
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

		/* 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;

712
713
714
715
716
717
718
719
		/* 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;

Linus Torvalds's avatar
Linus Torvalds committed
720
		ch = (sctp_chunkhdr_t *) ch_end;
721
	} while (ch_end < skb_tail_pointer(skb));
Linus Torvalds's avatar
Linus Torvalds committed
722
723
724
725
726
727
728
729
730
731

	return 0;

discard:
	return 1;
}

/* Insert endpoint into the hash table.  */
static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
{
732
	struct net *net = sock_net(ep->base.sk);
Linus Torvalds's avatar
Linus Torvalds committed
733
734
735
736
737
	struct sctp_ep_common *epb;
	struct sctp_hashbucket *head;

	epb = &ep->base;

738
	epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port);
Linus Torvalds's avatar
Linus Torvalds committed
739
740
741
	head = &sctp_ep_hashtable[epb->hashent];

	sctp_write_lock(&head->lock);
742
	hlist_add_head(&epb->node, &head->chain);
Linus Torvalds's avatar
Linus Torvalds committed
743
744
745
746
747
748
749
750
751
752
753
754
755
756
	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)
{
757
	struct net *net = sock_net(ep->base.sk);
Linus Torvalds's avatar
Linus Torvalds committed
758
759
760
761
762
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;

	epb = &ep->base;

763
	epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port);
Linus Torvalds's avatar
Linus Torvalds committed
764
765
766
767

	head = &sctp_ep_hashtable[epb->hashent];

	sctp_write_lock(&head->lock);
768
	hlist_del_init(&epb->node);
Linus Torvalds's avatar
Linus Torvalds committed
769
770
771
772
773
774
775
776
777
778
779
780
	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. */
781
782
static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
						const union sctp_addr *laddr)
Linus Torvalds's avatar
Linus Torvalds committed
783
784
785
786
787
788
{
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;
	struct sctp_endpoint *ep;
	int hash;

789
	hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port));
Linus Torvalds's avatar
Linus Torvalds committed
790
791
	head = &sctp_ep_hashtable[hash];
	read_lock(&head->lock);
792
	sctp_for_each_hentry(epb, &head->chain) {
Linus Torvalds's avatar
Linus Torvalds committed
793
		ep = sctp_ep(epb);
794
		if (sctp_endpoint_is_match(ep, net, laddr))
Linus Torvalds's avatar
Linus Torvalds committed
795
796
797
			goto hit;
	}

798
	ep = sctp_sk(net->sctp.ctl_sock)->ep;
Linus Torvalds's avatar
Linus Torvalds committed
799
800
801
802
803
804
805
806
807
808

hit:
	sctp_endpoint_hold(ep);
	read_unlock(&head->lock);
	return ep;
}

/* Insert association into the hash table.  */
static void __sctp_hash_established(struct sctp_association *asoc)
{
809
	struct net *net = sock_net(asoc->base.sk);
Linus Torvalds's avatar
Linus Torvalds committed
810
811
812
813
814
815
	struct sctp_ep_common *epb;
	struct sctp_hashbucket *head;

	epb = &asoc->base;

	/* Calculate which chain this entry will belong to. */
816
817
	epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port,
					 asoc->peer.port);
Linus Torvalds's avatar
Linus Torvalds committed
818
819
820
821

	head = &sctp_assoc_hashtable[epb->hashent];

	sctp_write_lock(&head->lock);
822
	hlist_add_head(&epb->node, &head->chain);
Linus Torvalds's avatar
Linus Torvalds committed
823
824
825
826
827
828
	sctp_write_unlock(&head->lock);
}

/* Add an association to the hash. Local BH-safe. */
void sctp_hash_established(struct sctp_association *asoc)
{
829
830
831
	if (asoc->temp)
		return;

Linus Torvalds's avatar
Linus Torvalds committed
832
833
834
835
836
837
838
839
	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)
{
840
	struct net *net = sock_net(asoc->base.sk);
Linus Torvalds's avatar
Linus Torvalds committed
841
842
843
844
845
	struct sctp_hashbucket *head;
	struct sctp_ep_common *epb;

	epb = &asoc->base;

846
	epb->hashent = sctp_assoc_hashfn(net, epb->bind_addr.port,
Linus Torvalds's avatar
Linus Torvalds committed
847
848
849
850
851
					 asoc->peer.port);

	head = &sctp_assoc_hashtable[epb->hashent];

	sctp_write_lock(&head->lock);
852
	hlist_del_init(&epb->node);
Linus Torvalds's avatar
Linus Torvalds committed
853
854
855
856
857
858
	sctp_write_unlock(&head->lock);
}

/* Remove association from the hash table.  Local BH-safe. */
void sctp_unhash_established(struct sctp_association *asoc)
{
859
860
861
	if (asoc->temp)
		return;

Linus Torvalds's avatar
Linus Torvalds committed
862
863
864
865
866
867
868
	sctp_local_bh_disable();
	__sctp_unhash_established(asoc);
	sctp_local_bh_enable();
}

/* Look up an association. */
static struct sctp_association *__sctp_lookup_association(
869
					struct net *net,
Linus Torvalds's avatar
Linus Torvalds committed
870
871
872
873
874
875
876
877
878
879
880
881
882
					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;
	int hash;

	/* Optimize here for direct hit, only listening connections can
	 * have wildcards anyways.
	 */
883
884
	hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port),
				 ntohs(peer->v4.sin_port));
Linus Torvalds's avatar
Linus Torvalds committed
885
886
	head = &sctp_assoc_hashtable[hash];
	read_lock(&head->lock);
887
	sctp_for_each_hentry(epb, &head->chain) {
Linus Torvalds's avatar
Linus Torvalds committed
888
		asoc = sctp_assoc(epb);
889
		transport = sctp_assoc_is_match(asoc, net, local, peer);
Linus Torvalds's avatar
Linus Torvalds committed
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
		if (transport)
			goto hit;
	}

	read_unlock(&head->lock);

	return NULL;

hit:
	*pt = transport;
	sctp_association_hold(asoc);
	read_unlock(&head->lock);
	return asoc;
}

/* Look up an association. BH-safe. */
906
static
907
908
struct sctp_association *sctp_lookup_association(struct net *net,
						 const union sctp_addr *laddr,
Linus Torvalds's avatar
Linus Torvalds committed
909
						 const union sctp_addr *paddr,
910
						 struct sctp_transport **transportp)
Linus Torvalds's avatar
Linus Torvalds committed
911
912
913
914
{
	struct sctp_association *asoc;

	sctp_local_bh_disable();
915
	asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
Linus Torvalds's avatar
Linus Torvalds committed
916
917
918
919
920
921
	sctp_local_bh_enable();

	return asoc;
}

/* Is there an association matching the given local and peer addresses? */
922
923
int sctp_has_association(struct net *net,
			 const union sctp_addr *laddr,
Linus Torvalds's avatar
Linus Torvalds committed
924
925
926
927
928
			 const union sctp_addr *paddr)
{
	struct sctp_association *asoc;
	struct sctp_transport *transport;

929
	if ((asoc = sctp_lookup_association(net, laddr, paddr, &transport))) {
Linus Torvalds's avatar
Linus Torvalds committed
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
		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.
 *
 */
955
956
static struct sctp_association *__sctp_rcv_init_lookup(struct net *net,
	struct sk_buff *skb,
Linus Torvalds's avatar
Linus Torvalds committed
957
958
959
960
961
	const union sctp_addr *laddr, struct sctp_transport **transportp)
{
	struct sctp_association *asoc;
	union sctp_addr addr;
	union sctp_addr *paddr = &addr;
962
	struct sctphdr *sh = sctp_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
	union sctp_params params;
	sctp_init_chunk_t *init;
	struct sctp_transport *transport;
	struct sctp_af *af;

	/*
	 * 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;

994
		af->from_addr_param(paddr, params.addr, sh->source, 0);
Linus Torvalds's avatar
Linus Torvalds committed
995

996
		asoc = __sctp_lookup_association(net, laddr, paddr, &transport);
Linus Torvalds's avatar
Linus Torvalds committed
997
998
999
1000
1001
1002
1003
		if (asoc)
			return asoc;
	}

	return NULL;
}

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
/* 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(
1019
					struct net *net,
1020
1021
					sctp_chunkhdr_t *ch,
					const union sctp_addr *laddr,
1022
					__be16 peer_port,
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
					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);

1033
	af = sctp_get_af_specific(param_type2af(param->p.type));
1034
1035
1036
1037
1038
	if (unlikely(!af))
		return NULL;

	af->from_addr_param(&paddr, param, peer_port, 0);

1039
	return __sctp_lookup_association(net, laddr, &paddr, transportp);
1040
1041
1042
}


1043
1044
1045
1046
1047
1048
1049
/* 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
Lucas De Marchi's avatar
Lucas De Marchi committed
1050
* to be looked at to find this association.
1051
*/
1052
1053
static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net,
				      struct sk_buff *skb,
1054
1055
1056
				      const union sctp_addr *laddr,
				      struct sctp_transport **transportp)
{
1057
1058
1059
1060
1061
1062
1063
1064
	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.
1065
	 */
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
	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:
1094
			    if (have_auth || net->sctp.addip_noauth)
1095
1096
				    asoc = __sctp_rcv_asconf_lookup(
							net, ch, laddr,
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
							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;
1111
1112
1113
1114
1115
1116
1117
1118
}

/*
 * 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.
 */
1119
1120
static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net,
				      struct sk_buff *skb,
1121
1122
1123
1124
1125
1126
1127
				      const union sctp_addr *laddr,
				      struct sctp_transport **transportp)
{
	sctp_chunkhdr_t *ch;

	ch = (sctp_chunkhdr_t *) skb->data;

1128
1129
1130
1131
1132
1133
1134
1135
	/* 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;

1136
1137
1138
1139
	/* If this is INIT/INIT-ACK look inside the chunk too. */
	switch (ch->type) {
	case SCTP_CID_INIT:
	case SCTP_CID_INIT_ACK:
1140
		return __sctp_rcv_init_lookup(net, skb, laddr, transportp);
1141
1142
		break;

1143
	default:
1144
		return __sctp_rcv_walk_lookup(net, skb, laddr, transportp);
1145
1146
1147
		break;
	}

1148

1149
1150
1151
	return NULL;
}

Linus Torvalds's avatar
Linus Torvalds committed
1152
/* Lookup an association for an inbound skb. */
1153
1154
static struct sctp_association *__sctp_rcv_lookup(struct net *net,
				      struct sk_buff *skb,
Linus Torvalds's avatar
Linus Torvalds committed
1155
1156
1157
1158
1159
1160
				      const union sctp_addr *paddr,
				      const union sctp_addr *laddr,
				      struct sctp_transport **transportp)
{
	struct sctp_association *asoc;

1161
	asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
Linus Torvalds's avatar
Linus Torvalds committed
1162
1163
1164
1165
1166
1167

	/* Further lookup for INIT/INIT-ACK packets.
	 * SCTP Implementors Guide, 2.18 Handling of address
	 * parameters within the INIT or INIT-ACK.
	 */
	if (!asoc)
1168
		asoc = __sctp_rcv_lookup_harder(net, skb, laddr, transportp);
Linus Torvalds's avatar
Linus Torvalds committed
1169
1170
1171

	return asoc;
}