Blame view
net/sctp/input.c
34.9 KB
47505b8bc treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
60c778b25 [SCTP]: Stop clai... |
2 |
/* SCTP kernel implementation |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 |
* 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 [SCTP]: Stop clai... |
10 |
* This file is part of the SCTP kernel implementation |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
* * These functions handle all input from the IP layer into SCTP. * |
1da177e4c Linux-2.6.12-rc2 |
14 15 |
* Please send any bug reports or fixes you make to the * email address(es): |
91705c61b net: sctp: trivia... |
16 |
* lksctp developers <linux-sctp@vger.kernel.org> |
1da177e4c Linux-2.6.12-rc2 |
17 |
* |
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 22 23 24 25 26 |
* 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> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 32 33 |
*/ #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 include cleanup: ... |
34 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 40 41 |
#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 [SCTP]: Use crc32... |
42 |
#include <net/sctp/checksum.h> |
dcfc23cac mib: add struct n... |
43 |
#include <net/net_namespace.h> |
0eb71a9da rhashtable: split... |
44 |
#include <linux/rhashtable.h> |
532ae2f10 sctp: do reusepor... |
45 |
#include <net/sock_reuseport.h> |
1da177e4c Linux-2.6.12-rc2 |
46 47 48 |
/* Forward declarations for internal helpers. */ static int sctp_rcv_ootb(struct sk_buff *); |
4110cc255 sctp: Make the as... |
49 50 |
static struct sctp_association *__sctp_rcv_lookup(struct net *net, struct sk_buff *skb, |
1da177e4c Linux-2.6.12-rc2 |
51 |
const union sctp_addr *paddr, |
575659936 sctp: fix a typo ... |
52 |
const union sctp_addr *laddr, |
1da177e4c Linux-2.6.12-rc2 |
53 |
struct sctp_transport **transportp); |
532ae2f10 sctp: do reusepor... |
54 55 56 57 |
static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( struct net *net, struct sk_buff *skb, const union sctp_addr *laddr, const union sctp_addr *daddr); |
1da177e4c Linux-2.6.12-rc2 |
58 |
static struct sctp_association *__sctp_lookup_association( |
4110cc255 sctp: Make the as... |
59 |
struct net *net, |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 |
const union sctp_addr *local, const union sctp_addr *peer, struct sctp_transport **pt); |
50b1a782f sctp: use limited... |
63 |
static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb); |
61c9fed41 [SCTP]: A better ... |
64 |
|
1da177e4c Linux-2.6.12-rc2 |
65 66 |
/* Calculate the SCTP checksum of an SCTP packet. */ |
b01a24078 sctp: Make the mi... |
67 |
static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
68 |
{ |
2c0fd387b [SCTP]: Introduce... |
69 |
struct sctphdr *sh = sctp_hdr(skb); |
4458f04c0 sctp: Clean up sc... |
70 |
__le32 cmp = sh->checksum; |
024ec3dea net/sctp: Refacto... |
71 |
__le32 val = sctp_compute_cksum(skb, 0); |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 |
if (val != cmp) { /* CRC failure, dump it. */ |
08e3baef6 net: sctp: rename... |
75 |
__SCTP_INC_STATS(net, SCTP_MIB_CHECKSUMERRORS); |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 |
return -1; } return 0; } |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 85 86 87 88 89 90 |
/* * 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; |
1da177e4c Linux-2.6.12-rc2 |
91 92 93 94 |
union sctp_addr src; union sctp_addr dest; int family; struct sctp_af *af; |
4cdadcbcb sctp: Make the en... |
95 |
struct net *net = dev_net(skb->dev); |
1dd27cde3 net: use skb_is_g... |
96 |
bool is_gso = skb_is_gso(skb) && skb_is_gso_sctp(skb); |
1da177e4c Linux-2.6.12-rc2 |
97 |
|
cb3f837ba sctp: fix checkpa... |
98 |
if (skb->pkt_type != PACKET_HOST) |
1da177e4c Linux-2.6.12-rc2 |
99 |
goto discard_it; |
08e3baef6 net: sctp: rename... |
100 |
__SCTP_INC_STATS(net, SCTP_MIB_INSCTPPACKS); |
1da177e4c Linux-2.6.12-rc2 |
101 |
|
3acb50c18 sctp: delay as mu... |
102 103 104 105 106 |
/* If packet is too small to contain a single chunk, let's not * waste time on it anymore. */ if (skb->len < sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + skb_transport_offset(skb)) |
28cd77527 [SCTP]: Always li... |
107 |
goto discard_it; |
4c2f24549 sctp: linearize e... |
108 109 110 111 |
/* If the packet is fragmented and we need to do crc checking, * it's better to just linearize it otherwise crc computing * takes longer. */ |
1dd27cde3 net: use skb_is_g... |
112 |
if ((!is_gso && skb_linearize(skb)) || |
4c2f24549 sctp: linearize e... |
113 |
!pskb_may_pull(skb, sizeof(struct sctphdr))) |
3acb50c18 sctp: delay as mu... |
114 |
goto discard_it; |
1da177e4c Linux-2.6.12-rc2 |
115 |
|
3acb50c18 sctp: delay as mu... |
116 |
/* Pull up the IP header. */ |
ea2ae17d6 [SK_BUFF]: Introd... |
117 |
__skb_pull(skb, skb_transport_offset(skb)); |
202863fe4 sctp: Change sctp... |
118 119 120 121 |
skb->csum_valid = 0; /* Previous value not applicable */ if (skb_csum_unnecessary(skb)) __skb_decr_checksum_unnecessary(skb); |
90017accf sctp: Add GSO sup... |
122 |
else if (!sctp_checksum_disable && |
1dd27cde3 net: use skb_is_g... |
123 |
!is_gso && |
90017accf sctp: Add GSO sup... |
124 |
sctp_rcv_checksum(net, skb) < 0) |
1da177e4c Linux-2.6.12-rc2 |
125 |
goto discard_it; |
202863fe4 sctp: Change sctp... |
126 |
skb->csum_valid = 1; |
1da177e4c Linux-2.6.12-rc2 |
127 |
|
3acb50c18 sctp: delay as mu... |
128 |
__skb_pull(skb, sizeof(struct sctphdr)); |
1da177e4c Linux-2.6.12-rc2 |
129 |
|
eddc9ec53 [SK_BUFF]: Introd... |
130 |
family = ipver2af(ip_hdr(skb)->version); |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 |
af = sctp_get_af_specific(family); if (unlikely(!af)) goto discard_it; |
e7487c86d sctp: avoid ident... |
134 |
SCTP_INPUT_CB(skb)->af = af; |
1da177e4c Linux-2.6.12-rc2 |
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
/* 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 [SCTP]: Reject sc... |
151 152 |
if (!af->addr_valid(&src, NULL, skb) || !af->addr_valid(&dest, NULL, skb)) |
1da177e4c Linux-2.6.12-rc2 |
153 |
goto discard_it; |
4110cc255 sctp: Make the as... |
154 |
asoc = __sctp_rcv_lookup(net, skb, &src, &dest, &transport); |
1c7d1fc14 [SCTP]: Switch sc... |
155 |
|
0fd9a65a7 [SCTP] Support SO... |
156 |
if (!asoc) |
532ae2f10 sctp: do reusepor... |
157 |
ep = __sctp_rcv_lookup_endpoint(net, skb, &dest, &src); |
0fd9a65a7 [SCTP] Support SO... |
158 159 160 161 162 163 164 165 166 |
/* 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 */ |
8d72651d8 sctp: fix checkpa... |
167 |
if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { |
dae399d7f sctp: hold transp... |
168 169 |
if (transport) { sctp_transport_put(transport); |
0fd9a65a7 [SCTP] Support SO... |
170 |
asoc = NULL; |
dae399d7f sctp: hold transp... |
171 |
transport = NULL; |
0fd9a65a7 [SCTP] Support SO... |
172 173 174 175 |
} else { sctp_endpoint_put(ep); ep = NULL; } |
2ce955035 sctp: Make the ct... |
176 |
sk = net->sctp.ctl_sock; |
0fd9a65a7 [SCTP] Support SO... |
177 178 |
ep = sctp_sk(sk)->ep; sctp_endpoint_hold(ep); |
0fd9a65a7 [SCTP] Support SO... |
179 180 |
rcvr = &ep->base; } |
1da177e4c Linux-2.6.12-rc2 |
181 182 183 184 185 186 187 188 189 |
/* * 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 Linux-2.6.12-rc2 |
190 |
if (sctp_rcv_ootb(skb)) { |
08e3baef6 net: sctp: rename... |
191 |
__SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES); |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 |
goto discard_release; } } |
1da177e4c Linux-2.6.12-rc2 |
195 196 |
if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family)) goto discard_release; |
895b5c9f2 netfilter: drop b... |
197 |
nf_reset_ct(skb); |
1da177e4c Linux-2.6.12-rc2 |
198 |
|
fda9ef5d6 [NET]: Fix sk->sk... |
199 |
if (sk_filter(sk, skb)) |
d808ad9ab [NET] SCTP: Fix w... |
200 |
goto discard_release; |
1da177e4c Linux-2.6.12-rc2 |
201 202 |
/* Create an SCTP packet structure. */ |
cea8768f3 sctp: allow sctp_... |
203 |
chunk = sctp_chunkify(skb, asoc, sk, GFP_ATOMIC); |
2babf9daa [SCTP]: Fix up sc... |
204 |
if (!chunk) |
1da177e4c Linux-2.6.12-rc2 |
205 |
goto discard_release; |
79af02c25 [SCTP]: Use struc... |
206 |
SCTP_INPUT_CB(skb)->chunk = chunk; |
1da177e4c Linux-2.6.12-rc2 |
207 |
|
1da177e4c Linux-2.6.12-rc2 |
208 209 210 211 |
/* Remember what endpoint is to handle this packet. */ chunk->rcvr = rcvr; /* Remember the SCTP header. */ |
3acb50c18 sctp: delay as mu... |
212 |
chunk->sctp_hdr = sctp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
213 214 |
/* Set the source and destination addresses of the incoming chunk. */ |
d55c41b11 [SCTP]: Switch ->... |
215 |
sctp_init_addrs(chunk, &src, &dest); |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 219 220 221 222 223 |
/* 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. */ |
5bc1d1b4a sctp: remove macr... |
224 |
bh_lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
225 |
|
ae53b5bd7 sctp: Fix another... |
226 227 228 229 230 231 232 233 |
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. */ |
5bc1d1b4a sctp: remove macr... |
234 |
bh_unlock_sock(sk); |
ae53b5bd7 sctp: Fix another... |
235 |
sk = rcvr->sk; |
5bc1d1b4a sctp: remove macr... |
236 |
bh_lock_sock(sk); |
ae53b5bd7 sctp: Fix another... |
237 |
} |
819be8108 sctp: add chunks ... |
238 |
if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) { |
50b1a782f sctp: use limited... |
239 |
if (sctp_add_backlog(sk, skb)) { |
5bc1d1b4a sctp: remove macr... |
240 |
bh_unlock_sock(sk); |
50b1a782f sctp: use limited... |
241 242 243 244 |
sctp_chunk_free(chunk); skb = NULL; /* sctp_chunk_free already freed the skb */ goto discard_release; } |
08e3baef6 net: sctp: rename... |
245 |
__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_BACKLOG); |
ac0b04627 [SCTP]: Extend /p... |
246 |
} else { |
08e3baef6 net: sctp: rename... |
247 |
__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_SOFTIRQ); |
61c9fed41 [SCTP]: A better ... |
248 |
sctp_inq_push(&chunk->rcvr->inqueue, chunk); |
ac0b04627 [SCTP]: Extend /p... |
249 |
} |
1da177e4c Linux-2.6.12-rc2 |
250 |
|
5bc1d1b4a sctp: remove macr... |
251 |
bh_unlock_sock(sk); |
61c9fed41 [SCTP]: A better ... |
252 253 |
/* Release the asoc/ep ref we took in the lookup calls. */ |
dae399d7f sctp: hold transp... |
254 255 |
if (transport) sctp_transport_put(transport); |
61c9fed41 [SCTP]: A better ... |
256 257 |
else sctp_endpoint_put(ep); |
7a48f923b [SCTP]: Fix poten... |
258 |
|
2babf9daa [SCTP]: Fix up sc... |
259 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
260 261 |
discard_it: |
08e3baef6 net: sctp: rename... |
262 |
__SCTP_INC_STATS(net, SCTP_MIB_IN_PKT_DISCARDS); |
1da177e4c Linux-2.6.12-rc2 |
263 |
kfree_skb(skb); |
2babf9daa [SCTP]: Fix up sc... |
264 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
265 266 |
discard_release: |
61c9fed41 [SCTP]: A better ... |
267 |
/* Release the asoc/ep ref we took in the lookup calls. */ |
dae399d7f sctp: hold transp... |
268 269 |
if (transport) sctp_transport_put(transport); |
0fd9a65a7 [SCTP] Support SO... |
270 |
else |
1da177e4c Linux-2.6.12-rc2 |
271 |
sctp_endpoint_put(ep); |
1da177e4c Linux-2.6.12-rc2 |
272 273 274 |
goto discard_it; } |
61c9fed41 [SCTP]: A better ... |
275 276 277 278 |
/* 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 Linux-2.6.12-rc2 |
279 280 281 |
*/ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) { |
79af02c25 [SCTP]: Use struc... |
282 |
struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
d808ad9ab [NET] SCTP: Fix w... |
283 |
struct sctp_inq *inqueue = &chunk->rcvr->inqueue; |
dae399d7f sctp: hold transp... |
284 |
struct sctp_transport *t = chunk->transport; |
d808ad9ab [NET] SCTP: Fix w... |
285 |
struct sctp_ep_common *rcvr = NULL; |
61c9fed41 [SCTP]: A better ... |
286 |
int backloged = 0; |
7a48f923b [SCTP]: Fix poten... |
287 |
|
d808ad9ab [NET] SCTP: Fix w... |
288 |
rcvr = chunk->rcvr; |
c4d2444e9 [SCTP]: Fix coupl... |
289 |
|
61c9fed41 [SCTP]: A better ... |
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
/* 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; |
eefc1b1d1 sctp: fix BH hand... |
312 |
local_bh_disable(); |
5bc1d1b4a sctp: remove macr... |
313 |
bh_lock_sock(sk); |
61c9fed41 [SCTP]: A better ... |
314 |
|
819be8108 sctp: add chunks ... |
315 |
if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) { |
8265792bf net: silence KCSA... |
316 |
if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) |
50b1a782f sctp: use limited... |
317 318 319 |
sctp_chunk_free(chunk); else backloged = 1; |
61c9fed41 [SCTP]: A better ... |
320 321 |
} else sctp_inq_push(inqueue, chunk); |
5bc1d1b4a sctp: remove macr... |
322 |
bh_unlock_sock(sk); |
eefc1b1d1 sctp: fix BH hand... |
323 |
local_bh_enable(); |
61c9fed41 [SCTP]: A better ... |
324 325 326 327 328 |
/* If the chunk was backloged again, don't drop refs */ if (backloged) return 0; } else { |
819be8108 sctp: add chunks ... |
329 |
if (!sctp_newsk_ready(sk)) { |
8265792bf net: silence KCSA... |
330 |
if (!sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) |
819be8108 sctp: add chunks ... |
331 332 333 334 335 |
return 0; sctp_chunk_free(chunk); } else { sctp_inq_push(inqueue, chunk); } |
61c9fed41 [SCTP]: A better ... |
336 337 338 339 340 |
} done: /* Release the refs we took in sctp_add_backlog */ if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) |
dae399d7f sctp: hold transp... |
341 |
sctp_transport_put(t); |
61c9fed41 [SCTP]: A better ... |
342 343 344 345 |
else if (SCTP_EP_TYPE_SOCKET == rcvr->type) sctp_endpoint_put(sctp_ep(rcvr)); else BUG(); |
d808ad9ab [NET] SCTP: Fix w... |
346 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
347 |
} |
50b1a782f sctp: use limited... |
348 |
static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) |
c4d2444e9 [SCTP]: Fix coupl... |
349 |
{ |
61c9fed41 [SCTP]: A better ... |
350 |
struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
dae399d7f sctp: hold transp... |
351 |
struct sctp_transport *t = chunk->transport; |
61c9fed41 [SCTP]: A better ... |
352 |
struct sctp_ep_common *rcvr = chunk->rcvr; |
50b1a782f sctp: use limited... |
353 |
int ret; |
c4d2444e9 [SCTP]: Fix coupl... |
354 |
|
8265792bf net: silence KCSA... |
355 |
ret = sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)); |
50b1a782f sctp: use limited... |
356 357 358 359 360 361 |
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) |
dae399d7f sctp: hold transp... |
362 |
sctp_transport_hold(t); |
50b1a782f sctp: use limited... |
363 364 365 366 367 368 |
else if (SCTP_EP_TYPE_SOCKET == rcvr->type) sctp_endpoint_hold(sctp_ep(rcvr)); else BUG(); } return ret; |
61c9fed41 [SCTP]: A better ... |
369 |
|
c4d2444e9 [SCTP]: Fix coupl... |
370 |
} |
1da177e4c Linux-2.6.12-rc2 |
371 372 373 374 |
/* Handle icmp frag needed error. */ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, struct sctp_transport *t, __u32 pmtu) { |
91bd6b1e0 sctp: Drop ICMP p... |
375 |
if (!t || (t->pathmtu <= pmtu)) |
52ccb8e90 [SCTP]: Update SC... |
376 |
return; |
8a4794914 [SCTP] Flag a pmt... |
377 |
if (sock_owned_by_user(sk)) { |
d805397c3 sctp: use the pmt... |
378 |
atomic_set(&t->mtu_info, pmtu); |
8a4794914 [SCTP] Flag a pmt... |
379 380 381 382 |
asoc->pmtu_pending = 1; t->pmtu_pending = 1; return; } |
cc35c3d1e sctp: do not retr... |
383 384 385 386 387 388 |
if (!(t->param_flags & SPP_PMTUD_ENABLE)) /* We can't allow retransmitting in such case, as the * retransmission would be sized just as before, and thus we * would get another icmp, and retransmit again. */ return; |
1da177e4c Linux-2.6.12-rc2 |
389 |
|
b6c5734db sctp: fix the han... |
390 391 392 393 394 395 |
/* Update transports view of the MTU. Return if no update was needed. * If an update wasn't needed/possible, it also doesn't make sense to * try to retransmit now. */ if (!sctp_transport_update_pmtu(t, pmtu)) return; |
52ccb8e90 [SCTP]: Update SC... |
396 |
|
cc35c3d1e sctp: do not retr... |
397 398 399 400 |
/* Update association pmtu. */ sctp_assoc_sync_pmtu(asoc); /* Retransmit with the new pmtu setting. */ |
52ccb8e90 [SCTP]: Update SC... |
401 |
sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); |
1da177e4c Linux-2.6.12-rc2 |
402 |
} |
ec18d9a26 ipv6: Add redirec... |
403 404 |
void sctp_icmp_redirect(struct sock *sk, struct sctp_transport *t, struct sk_buff *skb) |
55be7a9c6 ipv4: Add redirec... |
405 406 |
{ struct dst_entry *dst; |
1cc276cec sctp: add the mis... |
407 |
if (sock_owned_by_user(sk) || !t) |
55be7a9c6 ipv4: Add redirec... |
408 409 |
return; dst = sctp_transport_dst_check(t); |
1ed5c48f2 net: Remove check... |
410 |
if (dst) |
6700c2709 net: Pass optiona... |
411 |
dst->ops->redirect(dst, sk, skb); |
55be7a9c6 ipv4: Add redirec... |
412 |
} |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 416 417 418 419 420 421 422 423 424 |
/* * 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 [NET] SCTP: Fix w... |
425 426 |
struct sctp_association *asoc, struct sctp_transport *t) |
1da177e4c Linux-2.6.12-rc2 |
427 |
{ |
50b5d6ad6 sctp: Fix a race ... |
428 429 430 431 432 433 |
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))) |
057a10fa1 sctp: change to h... |
434 |
sctp_transport_hold(t); |
50b5d6ad6 sctp: Fix a race ... |
435 |
} |
50b5d6ad6 sctp: Fix a race ... |
436 |
} else { |
55e26eb95 sctp: Push struct... |
437 |
struct net *net = sock_net(sk); |
bb33381d0 net: sctp: rework... |
438 439 440 |
pr_debug("%s: unrecognized next header type " "encountered! ", __func__); |
25cc4ae91 net: remove redun... |
441 |
if (del_timer(&t->proto_unreach_timer)) |
057a10fa1 sctp: change to h... |
442 |
sctp_transport_put(t); |
1da177e4c Linux-2.6.12-rc2 |
443 |
|
55e26eb95 sctp: Push struct... |
444 |
sctp_do_sm(net, SCTP_EVENT_T_OTHER, |
50b5d6ad6 sctp: Fix a race ... |
445 446 447 448 |
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), asoc->state, asoc->ep, asoc, t, GFP_ATOMIC); } |
1da177e4c Linux-2.6.12-rc2 |
449 450 451 |
} /* Common lookup code for icmp/icmpv6 error handler. */ |
4110cc255 sctp: Make the as... |
452 |
struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, |
1da177e4c Linux-2.6.12-rc2 |
453 |
struct sctphdr *sctphdr, |
1da177e4c Linux-2.6.12-rc2 |
454 455 456 |
struct sctp_association **app, struct sctp_transport **tpp) { |
804ec7ebe sctp: fix ICMP pr... |
457 |
struct sctp_init_chunk *chunkhdr, _chunkhdr; |
1da177e4c Linux-2.6.12-rc2 |
458 459 460 461 |
union sctp_addr saddr; union sctp_addr daddr; struct sctp_af *af; struct sock *sk = NULL; |
8de8c8738 [SCTP]: Set sk_er... |
462 |
struct sctp_association *asoc; |
1da177e4c Linux-2.6.12-rc2 |
463 |
struct sctp_transport *transport = NULL; |
7115e632f sctp: Validate In... |
464 |
__u32 vtag = ntohl(sctphdr->vtag); |
1da177e4c Linux-2.6.12-rc2 |
465 |
|
d1ad1ff29 [SCTP]: Fix poten... |
466 |
*app = NULL; *tpp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 470 471 472 473 474 475 476 477 478 479 |
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. */ |
4110cc255 sctp: Make the as... |
480 |
asoc = __sctp_lookup_association(net, &saddr, &daddr, &transport); |
d1ad1ff29 [SCTP]: Fix poten... |
481 482 |
if (!asoc) return NULL; |
1da177e4c Linux-2.6.12-rc2 |
483 |
|
d1ad1ff29 [SCTP]: Fix poten... |
484 |
sk = asoc->base.sk; |
1da177e4c Linux-2.6.12-rc2 |
485 |
|
7115e632f sctp: Validate In... |
486 487 488 489 490 491 492 493 494 495 496 497 498 |
/* 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) { |
804ec7ebe sctp: fix ICMP pr... |
499 500 501 502 503 504 |
/* chunk header + first 4 octects of init header */ chunkhdr = skb_header_pointer(skb, skb_transport_offset(skb) + sizeof(struct sctphdr), sizeof(struct sctp_chunkhdr) + sizeof(__be32), &_chunkhdr); if (!chunkhdr || |
7115e632f sctp: Validate In... |
505 |
chunkhdr->chunk_hdr.type != SCTP_CID_INIT || |
804ec7ebe sctp: fix ICMP pr... |
506 |
ntohl(chunkhdr->init_hdr.init_tag) != asoc->c.my_vtag) |
7115e632f sctp: Validate In... |
507 |
goto out; |
804ec7ebe sctp: fix ICMP pr... |
508 |
|
7115e632f sctp: Validate In... |
509 |
} else if (vtag != asoc->c.peer_vtag) { |
d1ad1ff29 [SCTP]: Fix poten... |
510 511 |
goto out; } |
1da177e4c Linux-2.6.12-rc2 |
512 |
|
5bc1d1b4a sctp: remove macr... |
513 |
bh_lock_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
514 515 516 517 518 |
/* If too many ICMPs get dropped on busy * servers this needs to be solved differently. */ if (sock_owned_by_user(sk)) |
02a1d6e7a net: rename NET_{... |
519 |
__NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); |
1da177e4c Linux-2.6.12-rc2 |
520 |
|
1da177e4c Linux-2.6.12-rc2 |
521 522 523 524 525 |
*app = asoc; *tpp = transport; return sk; out: |
dae399d7f sctp: hold transp... |
526 |
sctp_transport_put(transport); |
1da177e4c Linux-2.6.12-rc2 |
527 528 529 530 |
return NULL; } /* Common cleanup code for icmp/icmpv6 error handler. */ |
dae399d7f sctp: hold transp... |
531 |
void sctp_err_finish(struct sock *sk, struct sctp_transport *t) |
887cf3d13 sctp: Add missing... |
532 |
__releases(&((__sk)->sk_lock.slock)) |
1da177e4c Linux-2.6.12-rc2 |
533 |
{ |
5bc1d1b4a sctp: remove macr... |
534 |
bh_unlock_sock(sk); |
dae399d7f sctp: hold transp... |
535 |
sctp_transport_put(t); |
1da177e4c Linux-2.6.12-rc2 |
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
} /* * 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. * */ |
32bbd8793 net: Convert prot... |
553 |
int sctp_v4_err(struct sk_buff *skb, __u32 info) |
1da177e4c Linux-2.6.12-rc2 |
554 |
{ |
b71d1d426 inet: constify ip... |
555 |
const struct iphdr *iph = (const struct iphdr *)skb->data; |
a27ef749e [SCTP]: Eliminate... |
556 |
const int ihlen = iph->ihl * 4; |
88c7664f1 [SK_BUFF]: Introd... |
557 558 |
const int type = icmp_hdr(skb)->type; const int code = icmp_hdr(skb)->code; |
1da177e4c Linux-2.6.12-rc2 |
559 |
struct sock *sk; |
8de8c8738 [SCTP]: Set sk_er... |
560 |
struct sctp_association *asoc = NULL; |
1da177e4c Linux-2.6.12-rc2 |
561 562 |
struct sctp_transport *transport; struct inet_sock *inet; |
aef6de511 sctp: Correct byt... |
563 |
__u16 saveip, savesctp; |
1da177e4c Linux-2.6.12-rc2 |
564 |
int err; |
4110cc255 sctp: Make the as... |
565 |
struct net *net = dev_net(skb->dev); |
1da177e4c Linux-2.6.12-rc2 |
566 |
|
1da177e4c Linux-2.6.12-rc2 |
567 |
/* Fix up skb to look at the embedded net header. */ |
b0e380b1d [SK_BUFF]: unions... |
568 569 |
saveip = skb->network_header; savesctp = skb->transport_header; |
31c7711b5 [SK_BUFF]: Some m... |
570 |
skb_reset_network_header(skb); |
a27ef749e [SCTP]: Eliminate... |
571 |
skb_set_transport_header(skb, ihlen); |
4110cc255 sctp: Make the as... |
572 |
sk = sctp_err_lookup(net, AF_INET, skb, sctp_hdr(skb), &asoc, &transport); |
2e07fa9cd [SK_BUFF]: Use of... |
573 |
/* Put back, the original values. */ |
b0e380b1d [SK_BUFF]: unions... |
574 575 |
skb->network_header = saveip; skb->transport_header = savesctp; |
1da177e4c Linux-2.6.12-rc2 |
576 |
if (!sk) { |
5d3848bc3 net: rename ICMP_... |
577 |
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS); |
32bbd8793 net: Convert prot... |
578 |
return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
} /* 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) { |
3822a5ff4 sctp: align MTU t... |
594 |
sctp_icmp_frag_needed(sk, asoc, transport, |
e2f036a97 sctp: rename WORD... |
595 |
SCTP_TRUNC4(info)); |
1da177e4c Linux-2.6.12-rc2 |
596 |
goto out_unlock; |
8d72651d8 sctp: fix checkpa... |
597 |
} else { |
1da177e4c Linux-2.6.12-rc2 |
598 |
if (ICMP_PROT_UNREACH == code) { |
d1ad1ff29 [SCTP]: Fix poten... |
599 |
sctp_icmp_proto_unreachable(sk, asoc, |
1da177e4c Linux-2.6.12-rc2 |
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
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; |
55be7a9c6 ipv4: Add redirec... |
615 616 |
case ICMP_REDIRECT: sctp_icmp_redirect(sk, transport, skb); |
3f96a5321 net: sctp: rfc444... |
617 |
/* Fall through to out_unlock. */ |
1da177e4c Linux-2.6.12-rc2 |
618 619 620 621 622 623 624 625 626 627 628 629 630 |
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: |
dae399d7f sctp: hold transp... |
631 |
sctp_err_finish(sk, transport); |
32bbd8793 net: Convert prot... |
632 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
633 634 635 636 637 638 639 640 641 642 643 644 645 646 |
} /* * 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 sctp: make locall... |
647 |
static int sctp_rcv_ootb(struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
648 |
{ |
922dbc5be sctp: remove the ... |
649 |
struct sctp_chunkhdr *ch, _ch; |
3acb50c18 sctp: delay as mu... |
650 |
int ch_end, offset = 0; |
1da177e4c Linux-2.6.12-rc2 |
651 652 |
/* Scan through all the chunks in the packet. */ |
a7d1f1b66 [SCTP]: Fix sctp_... |
653 |
do { |
3acb50c18 sctp: delay as mu... |
654 |
/* Make sure we have at least the header there */ |
922dbc5be sctp: remove the ... |
655 |
if (offset + sizeof(_ch) > skb->len) |
3acb50c18 sctp: delay as mu... |
656 657 658 |
break; ch = skb_header_pointer(skb, offset, sizeof(*ch), &_ch); |
a7d1f1b66 [SCTP]: Fix sctp_... |
659 |
/* Break out if chunk length is less then minimal. */ |
922dbc5be sctp: remove the ... |
660 |
if (ntohs(ch->length) < sizeof(_ch)) |
a7d1f1b66 [SCTP]: Fix sctp_... |
661 |
break; |
e2f036a97 sctp: rename WORD... |
662 |
ch_end = offset + SCTP_PAD4(ntohs(ch->length)); |
3acb50c18 sctp: delay as mu... |
663 |
if (ch_end > skb->len) |
a7d1f1b66 [SCTP]: Fix sctp_... |
664 |
break; |
1da177e4c Linux-2.6.12-rc2 |
665 666 667 668 669 670 671 672 673 674 675 676 677 678 |
/* 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 SCTP: Discard OOT... |
679 680 681 682 683 684 685 |
/* 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; |
3acb50c18 sctp: delay as mu... |
686 687 |
offset = ch_end; } while (ch_end < skb->len); |
1da177e4c Linux-2.6.12-rc2 |
688 689 690 691 692 693 694 695 |
return 0; discard: return 1; } /* Insert endpoint into the hash table. */ |
76c6d988a sctp: add sock_re... |
696 |
static int __sctp_hash_endpoint(struct sctp_endpoint *ep) |
1da177e4c Linux-2.6.12-rc2 |
697 |
{ |
76c6d988a sctp: add sock_re... |
698 699 |
struct sock *sk = ep->base.sk; struct net *net = sock_net(sk); |
1da177e4c Linux-2.6.12-rc2 |
700 |
struct sctp_hashbucket *head; |
76c6d988a sctp: add sock_re... |
701 |
struct sctp_ep_common *epb; |
1da177e4c Linux-2.6.12-rc2 |
702 703 |
epb = &ep->base; |
4cdadcbcb sctp: Make the en... |
704 |
epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); |
1da177e4c Linux-2.6.12-rc2 |
705 |
head = &sctp_ep_hashtable[epb->hashent]; |
76c6d988a sctp: add sock_re... |
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
if (sk->sk_reuseport) { bool any = sctp_is_ep_boundall(sk); struct sctp_ep_common *epb2; struct list_head *list; int cnt = 0, err = 1; list_for_each(list, &ep->base.bind_addr.address_list) cnt++; sctp_for_each_hentry(epb2, &head->chain) { struct sock *sk2 = epb2->sk; if (!net_eq(sock_net(sk2), net) || sk2 == sk || !uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) || !sk2->sk_reuseport) continue; err = sctp_bind_addrs_check(sctp_sk(sk2), sctp_sk(sk), cnt); if (!err) { err = reuseport_add_sock(sk, sk2, any); if (err) return err; break; } else if (err < 0) { return err; } } if (err) { err = reuseport_alloc(sk, any); if (err) return err; } } |
387602dfd sctp: remove macr... |
741 |
write_lock(&head->lock); |
d970dbf84 SCTP: Convert cus... |
742 |
hlist_add_head(&epb->node, &head->chain); |
387602dfd sctp: remove macr... |
743 |
write_unlock(&head->lock); |
76c6d988a sctp: add sock_re... |
744 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
745 746 747 |
} /* Add an endpoint to the hash. Local BH-safe. */ |
76c6d988a sctp: add sock_re... |
748 |
int sctp_hash_endpoint(struct sctp_endpoint *ep) |
1da177e4c Linux-2.6.12-rc2 |
749 |
{ |
76c6d988a sctp: add sock_re... |
750 |
int err; |
79b91130a sctp: remove macr... |
751 |
local_bh_disable(); |
76c6d988a sctp: add sock_re... |
752 |
err = __sctp_hash_endpoint(ep); |
79b91130a sctp: remove macr... |
753 |
local_bh_enable(); |
76c6d988a sctp: add sock_re... |
754 755 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
756 757 758 759 760 |
} /* Remove endpoint from the hash table. */ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) { |
76c6d988a sctp: add sock_re... |
761 |
struct sock *sk = ep->base.sk; |
1da177e4c Linux-2.6.12-rc2 |
762 763 764 765 |
struct sctp_hashbucket *head; struct sctp_ep_common *epb; epb = &ep->base; |
76c6d988a sctp: add sock_re... |
766 |
epb->hashent = sctp_ep_hashfn(sock_net(sk), epb->bind_addr.port); |
1da177e4c Linux-2.6.12-rc2 |
767 768 |
head = &sctp_ep_hashtable[epb->hashent]; |
76c6d988a sctp: add sock_re... |
769 770 |
if (rcu_access_pointer(sk->sk_reuseport_cb)) reuseport_detach_sock(sk); |
387602dfd sctp: remove macr... |
771 |
write_lock(&head->lock); |
2eebc1e18 sctp: Fix list co... |
772 |
hlist_del_init(&epb->node); |
387602dfd sctp: remove macr... |
773 |
write_unlock(&head->lock); |
1da177e4c Linux-2.6.12-rc2 |
774 775 776 777 778 |
} /* Remove endpoint from the hash. Local BH-safe. */ void sctp_unhash_endpoint(struct sctp_endpoint *ep) { |
79b91130a sctp: remove macr... |
779 |
local_bh_disable(); |
1da177e4c Linux-2.6.12-rc2 |
780 |
__sctp_unhash_endpoint(ep); |
79b91130a sctp: remove macr... |
781 |
local_bh_enable(); |
1da177e4c Linux-2.6.12-rc2 |
782 |
} |
532ae2f10 sctp: do reusepor... |
783 784 785 786 787 788 789 790 791 792 793 794 795 |
static inline __u32 sctp_hashfn(const struct net *net, __be16 lport, const union sctp_addr *paddr, __u32 seed) { __u32 addr; if (paddr->sa.sa_family == AF_INET6) addr = jhash(&paddr->v6.sin6_addr, 16, seed); else addr = (__force __u32)paddr->v4.sin_addr.s_addr; return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 | (__force __u32)lport, net_hash_mix(net), seed); } |
1da177e4c Linux-2.6.12-rc2 |
796 |
/* Look up an endpoint. */ |
532ae2f10 sctp: do reusepor... |
797 798 799 800 |
static struct sctp_endpoint *__sctp_rcv_lookup_endpoint( struct net *net, struct sk_buff *skb, const union sctp_addr *laddr, const union sctp_addr *paddr) |
1da177e4c Linux-2.6.12-rc2 |
801 802 803 804 |
{ struct sctp_hashbucket *head; struct sctp_ep_common *epb; struct sctp_endpoint *ep; |
532ae2f10 sctp: do reusepor... |
805 806 |
struct sock *sk; __be16 lport; |
1da177e4c Linux-2.6.12-rc2 |
807 |
int hash; |
532ae2f10 sctp: do reusepor... |
808 809 |
lport = laddr->v4.sin_port; hash = sctp_ep_hashfn(net, ntohs(lport)); |
1da177e4c Linux-2.6.12-rc2 |
810 811 |
head = &sctp_ep_hashtable[hash]; read_lock(&head->lock); |
b67bfe0d4 hlist: drop the n... |
812 |
sctp_for_each_hentry(epb, &head->chain) { |
1da177e4c Linux-2.6.12-rc2 |
813 |
ep = sctp_ep(epb); |
4cdadcbcb sctp: Make the en... |
814 |
if (sctp_endpoint_is_match(ep, net, laddr)) |
1da177e4c Linux-2.6.12-rc2 |
815 816 |
goto hit; } |
2ce955035 sctp: Make the ct... |
817 |
ep = sctp_sk(net->sctp.ctl_sock)->ep; |
1da177e4c Linux-2.6.12-rc2 |
818 819 |
hit: |
532ae2f10 sctp: do reusepor... |
820 821 822 823 824 825 826 827 828 |
sk = ep->base.sk; if (sk->sk_reuseport) { __u32 phash = sctp_hashfn(net, lport, paddr, 0); sk = reuseport_select_sock(sk, phash, skb, sizeof(struct sctphdr)); if (sk) ep = sctp_sk(sk)->ep; } |
1da177e4c Linux-2.6.12-rc2 |
829 |
sctp_endpoint_hold(ep); |
1da177e4c Linux-2.6.12-rc2 |
830 831 832 |
read_unlock(&head->lock); return ep; } |
d6c0256a6 sctp: add the rha... |
833 834 |
/* rhashtable for transport */ struct sctp_hash_cmp_arg { |
7fda702f9 sctp: use new rhl... |
835 836 |
const union sctp_addr *paddr; const struct net *net; |
8d32503ef sctp: fix some ty... |
837 |
__be16 lport; |
d6c0256a6 sctp: add the rha... |
838 839 840 841 842 |
}; static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, const void *ptr) { |
715f5552b sctp: hold the tr... |
843 |
struct sctp_transport *t = (struct sctp_transport *)ptr; |
d6c0256a6 sctp: add the rha... |
844 |
const struct sctp_hash_cmp_arg *x = arg->key; |
715f5552b sctp: hold the tr... |
845 |
int err = 1; |
d6c0256a6 sctp: add the rha... |
846 |
|
d6c0256a6 sctp: add the rha... |
847 |
if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) |
715f5552b sctp: hold the tr... |
848 849 850 |
return err; if (!sctp_transport_hold(t)) return err; |
312434617 sctp: cache netns... |
851 |
if (!net_eq(t->asoc->base.net, x->net)) |
7fda702f9 sctp: use new rhl... |
852 853 |
goto out; if (x->lport != htons(t->asoc->base.bind_addr.port)) |
715f5552b sctp: hold the tr... |
854 |
goto out; |
d6c0256a6 sctp: add the rha... |
855 |
|
715f5552b sctp: hold the tr... |
856 857 858 859 |
err = 0; out: sctp_transport_put(t); return err; |
d6c0256a6 sctp: add the rha... |
860 |
} |
8d32503ef sctp: fix some ty... |
861 |
static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed) |
d6c0256a6 sctp: add the rha... |
862 863 |
{ const struct sctp_transport *t = data; |
d6c0256a6 sctp: add the rha... |
864 |
|
312434617 sctp: cache netns... |
865 |
return sctp_hashfn(t->asoc->base.net, |
532ae2f10 sctp: do reusepor... |
866 867 |
htons(t->asoc->base.bind_addr.port), &t->ipaddr, seed); |
d6c0256a6 sctp: add the rha... |
868 |
} |
8d32503ef sctp: fix some ty... |
869 |
static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed) |
d6c0256a6 sctp: add the rha... |
870 871 |
{ const struct sctp_hash_cmp_arg *x = data; |
d6c0256a6 sctp: add the rha... |
872 |
|
532ae2f10 sctp: do reusepor... |
873 |
return sctp_hashfn(x->net, x->lport, x->paddr, seed); |
d6c0256a6 sctp: add the rha... |
874 875 876 877 878 879 880 881 882 883 884 885 |
} static const struct rhashtable_params sctp_hash_params = { .head_offset = offsetof(struct sctp_transport, node), .hashfn = sctp_hash_key, .obj_hashfn = sctp_hash_obj, .obj_cmpfn = sctp_hash_cmp, .automatic_shrinking = true, }; int sctp_transport_hashtable_init(void) { |
7fda702f9 sctp: use new rhl... |
886 |
return rhltable_init(&sctp_transport_hashtable, &sctp_hash_params); |
d6c0256a6 sctp: add the rha... |
887 888 889 890 |
} void sctp_transport_hashtable_destroy(void) { |
7fda702f9 sctp: use new rhl... |
891 |
rhltable_destroy(&sctp_transport_hashtable); |
d6c0256a6 sctp: add the rha... |
892 |
} |
7fda702f9 sctp: use new rhl... |
893 |
int sctp_hash_transport(struct sctp_transport *t) |
d6c0256a6 sctp: add the rha... |
894 |
{ |
cd2b70875 sctp: check dupli... |
895 896 |
struct sctp_transport *transport; struct rhlist_head *tmp, *list; |
d6c0256a6 sctp: add the rha... |
897 |
struct sctp_hash_cmp_arg arg; |
7fda702f9 sctp: use new rhl... |
898 |
int err; |
d6c0256a6 sctp: add the rha... |
899 |
|
dd7445ad6 sctp: the temp as... |
900 |
if (t->asoc->temp) |
7fda702f9 sctp: use new rhl... |
901 |
return 0; |
dd7445ad6 sctp: the temp as... |
902 |
|
4e7696d90 sctp: get netns f... |
903 |
arg.net = t->asoc->base.net; |
7fda702f9 sctp: use new rhl... |
904 905 |
arg.paddr = &t->ipaddr; arg.lport = htons(t->asoc->base.bind_addr.port); |
d6c0256a6 sctp: add the rha... |
906 |
|
5179b2669 sctp: call rcu_re... |
907 |
rcu_read_lock(); |
cd2b70875 sctp: check dupli... |
908 909 910 911 912 |
list = rhltable_lookup(&sctp_transport_hashtable, &arg, sctp_hash_params); rhl_for_each_entry_rcu(transport, tmp, list, node) if (transport->asoc->ep == t->asoc->ep) { |
5179b2669 sctp: call rcu_re... |
913 |
rcu_read_unlock(); |
27af86bb0 sctp: do not pr_e... |
914 |
return -EEXIST; |
cd2b70875 sctp: check dupli... |
915 |
} |
5179b2669 sctp: call rcu_re... |
916 |
rcu_read_unlock(); |
cd2b70875 sctp: check dupli... |
917 |
|
7fda702f9 sctp: use new rhl... |
918 919 920 921 922 923 924 |
err = rhltable_insert_key(&sctp_transport_hashtable, &arg, &t->node, sctp_hash_params); if (err) pr_err_once("insert transport fail, errno %d ", err); return err; |
d6c0256a6 sctp: add the rha... |
925 926 927 928 |
} void sctp_unhash_transport(struct sctp_transport *t) { |
dd7445ad6 sctp: the temp as... |
929 930 |
if (t->asoc->temp) return; |
7fda702f9 sctp: use new rhl... |
931 932 |
rhltable_remove(&sctp_transport_hashtable, &t->node, sctp_hash_params); |
d6c0256a6 sctp: add the rha... |
933 |
} |
7fda702f9 sctp: use new rhl... |
934 |
/* return a transport with holding it */ |
d6c0256a6 sctp: add the rha... |
935 936 937 938 939 |
struct sctp_transport *sctp_addrs_lookup_transport( struct net *net, const union sctp_addr *laddr, const union sctp_addr *paddr) { |
7fda702f9 sctp: use new rhl... |
940 941 |
struct rhlist_head *tmp, *list; struct sctp_transport *t; |
d6c0256a6 sctp: add the rha... |
942 |
struct sctp_hash_cmp_arg arg = { |
d6c0256a6 sctp: add the rha... |
943 944 |
.paddr = paddr, .net = net, |
7fda702f9 sctp: use new rhl... |
945 |
.lport = laddr->v4.sin_port, |
d6c0256a6 sctp: add the rha... |
946 |
}; |
7fda702f9 sctp: use new rhl... |
947 948 949 950 951 952 953 954 955 956 957 958 959 960 |
list = rhltable_lookup(&sctp_transport_hashtable, &arg, sctp_hash_params); rhl_for_each_entry_rcu(t, tmp, list, node) { if (!sctp_transport_hold(t)) continue; if (sctp_bind_addr_match(&t->asoc->base.bind_addr, laddr, sctp_sk(t->asoc->base.sk))) return t; sctp_transport_put(t); } return NULL; |
d6c0256a6 sctp: add the rha... |
961 |
} |
7fda702f9 sctp: use new rhl... |
962 |
/* return a transport without holding it, as it's only used under sock lock */ |
d6c0256a6 sctp: add the rha... |
963 964 965 966 |
struct sctp_transport *sctp_epaddr_lookup_transport( const struct sctp_endpoint *ep, const union sctp_addr *paddr) { |
7fda702f9 sctp: use new rhl... |
967 968 |
struct rhlist_head *tmp, *list; struct sctp_transport *t; |
65a5124a7 sctp: support to ... |
969 |
struct sctp_hash_cmp_arg arg = { |
65a5124a7 sctp: support to ... |
970 |
.paddr = paddr, |
4e7696d90 sctp: get netns f... |
971 |
.net = ep->base.net, |
7fda702f9 sctp: use new rhl... |
972 |
.lport = htons(ep->base.bind_addr.port), |
65a5124a7 sctp: support to ... |
973 |
}; |
d6c0256a6 sctp: add the rha... |
974 |
|
7fda702f9 sctp: use new rhl... |
975 976 977 978 979 980 981 982 |
list = rhltable_lookup(&sctp_transport_hashtable, &arg, sctp_hash_params); rhl_for_each_entry_rcu(t, tmp, list, node) if (ep == t->asoc->ep) return t; return NULL; |
d6c0256a6 sctp: add the rha... |
983 |
} |
1da177e4c Linux-2.6.12-rc2 |
984 985 |
/* Look up an association. */ static struct sctp_association *__sctp_lookup_association( |
4110cc255 sctp: Make the as... |
986 |
struct net *net, |
1da177e4c Linux-2.6.12-rc2 |
987 988 989 990 |
const union sctp_addr *local, const union sctp_addr *peer, struct sctp_transport **pt) { |
4f0087812 sctp: apply rhash... |
991 |
struct sctp_transport *t; |
1eed67793 sctp: fix the tra... |
992 |
struct sctp_association *asoc = NULL; |
1da177e4c Linux-2.6.12-rc2 |
993 |
|
4f0087812 sctp: apply rhash... |
994 |
t = sctp_addrs_lookup_transport(net, local, peer); |
7fda702f9 sctp: use new rhl... |
995 |
if (!t) |
1eed67793 sctp: fix the tra... |
996 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
997 |
|
1eed67793 sctp: fix the tra... |
998 |
asoc = t->asoc; |
4f0087812 sctp: apply rhash... |
999 |
*pt = t; |
1da177e4c Linux-2.6.12-rc2 |
1000 |
|
1eed67793 sctp: fix the tra... |
1001 |
out: |
1eed67793 sctp: fix the tra... |
1002 |
return asoc; |
1da177e4c Linux-2.6.12-rc2 |
1003 |
} |
4f0087812 sctp: apply rhash... |
1004 |
/* Look up an association. protected by RCU read lock */ |
dda919285 net: sctp: remove... |
1005 |
static |
4110cc255 sctp: Make the as... |
1006 1007 |
struct sctp_association *sctp_lookup_association(struct net *net, const union sctp_addr *laddr, |
1da177e4c Linux-2.6.12-rc2 |
1008 |
const union sctp_addr *paddr, |
dda919285 net: sctp: remove... |
1009 |
struct sctp_transport **transportp) |
1da177e4c Linux-2.6.12-rc2 |
1010 1011 |
{ struct sctp_association *asoc; |
f46c7011b sctp: move rcu_re... |
1012 |
rcu_read_lock(); |
4110cc255 sctp: Make the as... |
1013 |
asoc = __sctp_lookup_association(net, laddr, paddr, transportp); |
f46c7011b sctp: move rcu_re... |
1014 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
1015 1016 1017 1018 1019 |
return asoc; } /* Is there an association matching the given local and peer addresses? */ |
530665385 sctp: remove unne... |
1020 1021 1022 |
bool sctp_has_association(struct net *net, const union sctp_addr *laddr, const union sctp_addr *paddr) |
1da177e4c Linux-2.6.12-rc2 |
1023 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1024 |
struct sctp_transport *transport; |
530665385 sctp: remove unne... |
1025 |
if (sctp_lookup_association(net, laddr, paddr, &transport)) { |
dae399d7f sctp: hold transp... |
1026 |
sctp_transport_put(transport); |
530665385 sctp: remove unne... |
1027 |
return true; |
1da177e4c Linux-2.6.12-rc2 |
1028 |
} |
530665385 sctp: remove unne... |
1029 |
return false; |
1da177e4c Linux-2.6.12-rc2 |
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
} /* * 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. * */ |
4110cc255 sctp: Make the as... |
1050 1051 |
static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, struct sk_buff *skb, |
1da177e4c Linux-2.6.12-rc2 |
1052 1053 1054 1055 1056 |
const union sctp_addr *laddr, struct sctp_transport **transportp) { struct sctp_association *asoc; union sctp_addr addr; union sctp_addr *paddr = &addr; |
2c0fd387b [SCTP]: Introduce... |
1057 |
struct sctphdr *sh = sctp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1058 |
union sctp_params params; |
01a992bea sctp: remove the ... |
1059 |
struct sctp_init_chunk *init; |
1da177e4c Linux-2.6.12-rc2 |
1060 |
struct sctp_af *af; |
1da177e4c Linux-2.6.12-rc2 |
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 |
/* * 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. */ |
01a992bea sctp: remove the ... |
1077 |
init = (struct sctp_init_chunk *)skb->data; |
1da177e4c Linux-2.6.12-rc2 |
1078 1079 1080 1081 1082 1083 1084 1085 |
/* 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 [SCTP]: Switch ->... |
1086 |
af->from_addr_param(paddr, params.addr, sh->source, 0); |
1da177e4c Linux-2.6.12-rc2 |
1087 |
|
7c17fcc72 sctp: return back... |
1088 |
asoc = __sctp_lookup_association(net, laddr, paddr, transportp); |
1da177e4c Linux-2.6.12-rc2 |
1089 1090 1091 1092 1093 1094 |
if (asoc) return asoc; } return NULL; } |
df2185771 [SCTP]: Update as... |
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 |
/* 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( |
4110cc255 sctp: Make the as... |
1110 |
struct net *net, |
922dbc5be sctp: remove the ... |
1111 |
struct sctp_chunkhdr *ch, |
df2185771 [SCTP]: Update as... |
1112 |
const union sctp_addr *laddr, |
bc92dd194 [SCTP]: fix misan... |
1113 |
__be16 peer_port, |
df2185771 [SCTP]: Update as... |
1114 1115 |
struct sctp_transport **transportp) { |
68d754694 sctp: remove the ... |
1116 |
struct sctp_addip_chunk *asconf = (struct sctp_addip_chunk *)ch; |
df2185771 [SCTP]: Update as... |
1117 1118 1119 1120 1121 1122 |
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 sctp: use common ... |
1123 |
af = sctp_get_af_specific(param_type2af(param->p.type)); |
df2185771 [SCTP]: Update as... |
1124 1125 1126 1127 |
if (unlikely(!af)) return NULL; af->from_addr_param(&paddr, param, peer_port, 0); |
4110cc255 sctp: Make the as... |
1128 |
return __sctp_lookup_association(net, laddr, &paddr, transportp); |
df2185771 [SCTP]: Update as... |
1129 |
} |
bbd0d5980 [SCTP]: Implement... |
1130 1131 1132 1133 1134 1135 1136 |
/* 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 Fix common misspe... |
1137 |
* to be looked at to find this association. |
bbd0d5980 [SCTP]: Implement... |
1138 |
*/ |
4110cc255 sctp: Make the as... |
1139 1140 |
static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, struct sk_buff *skb, |
bbd0d5980 [SCTP]: Implement... |
1141 1142 1143 |
const union sctp_addr *laddr, struct sctp_transport **transportp) { |
df2185771 [SCTP]: Update as... |
1144 |
struct sctp_association *asoc = NULL; |
922dbc5be sctp: remove the ... |
1145 |
struct sctp_chunkhdr *ch; |
df2185771 [SCTP]: Update as... |
1146 1147 1148 1149 1150 1151 |
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 [SCTP]: Implement... |
1152 |
*/ |
922dbc5be sctp: remove the ... |
1153 |
ch = (struct sctp_chunkhdr *)skb->data; |
df2185771 [SCTP]: Update as... |
1154 1155 |
do { /* Break out if chunk length is less then minimal. */ |
922dbc5be sctp: remove the ... |
1156 |
if (ntohs(ch->length) < sizeof(*ch)) |
df2185771 [SCTP]: Update as... |
1157 |
break; |
e2f036a97 sctp: rename WORD... |
1158 |
ch_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length)); |
df2185771 [SCTP]: Update as... |
1159 1160 |
if (ch_end > skb_tail_pointer(skb)) break; |
cb3f837ba sctp: fix checkpa... |
1161 |
switch (ch->type) { |
f7010e614 sctp: fix checkpa... |
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 |
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 || net->sctp.addip_noauth) asoc = __sctp_rcv_asconf_lookup( net, ch, laddr, sctp_hdr(skb)->source, transportp); default: break; |
df2185771 [SCTP]: Update as... |
1186 1187 1188 1189 |
} if (asoc) break; |
922dbc5be sctp: remove the ... |
1190 |
ch = (struct sctp_chunkhdr *)ch_end; |
df2185771 [SCTP]: Update as... |
1191 1192 1193 1194 |
chunk_num++; } while (ch_end < skb_tail_pointer(skb)); return asoc; |
bbd0d5980 [SCTP]: Implement... |
1195 1196 1197 1198 1199 1200 1201 1202 |
} /* * 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. */ |
4110cc255 sctp: Make the as... |
1203 1204 |
static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, struct sk_buff *skb, |
bbd0d5980 [SCTP]: Implement... |
1205 1206 1207 |
const union sctp_addr *laddr, struct sctp_transport **transportp) { |
922dbc5be sctp: remove the ... |
1208 |
struct sctp_chunkhdr *ch; |
bbd0d5980 [SCTP]: Implement... |
1209 |
|
90017accf sctp: Add GSO sup... |
1210 1211 1212 1213 1214 |
/* We do not allow GSO frames here as we need to linearize and * then cannot guarantee frame boundaries. This shouldn't be an * issue as packets hitting this are mostly INIT or INIT-ACK and * those cannot be on GSO-style anyway. */ |
1dd27cde3 net: use skb_is_g... |
1215 |
if (skb_is_gso(skb) && skb_is_gso_sctp(skb)) |
90017accf sctp: Add GSO sup... |
1216 |
return NULL; |
922dbc5be sctp: remove the ... |
1217 |
ch = (struct sctp_chunkhdr *)skb->data; |
bbd0d5980 [SCTP]: Implement... |
1218 |
|
df2185771 [SCTP]: Update as... |
1219 1220 1221 1222 1223 |
/* 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. */ |
e2f036a97 sctp: rename WORD... |
1224 |
if (SCTP_PAD4(ntohs(ch->length)) > skb->len) |
df2185771 [SCTP]: Update as... |
1225 |
return NULL; |
bbd0d5980 [SCTP]: Implement... |
1226 |
/* If this is INIT/INIT-ACK look inside the chunk too. */ |
f482f2fcd sctp: remove the ... |
1227 |
if (ch->type == SCTP_CID_INIT || ch->type == SCTP_CID_INIT_ACK) |
4110cc255 sctp: Make the as... |
1228 |
return __sctp_rcv_init_lookup(net, skb, laddr, transportp); |
bbd0d5980 [SCTP]: Implement... |
1229 |
|
f482f2fcd sctp: remove the ... |
1230 |
return __sctp_rcv_walk_lookup(net, skb, laddr, transportp); |
bbd0d5980 [SCTP]: Implement... |
1231 |
} |
1da177e4c Linux-2.6.12-rc2 |
1232 |
/* Lookup an association for an inbound skb. */ |
4110cc255 sctp: Make the as... |
1233 1234 |
static struct sctp_association *__sctp_rcv_lookup(struct net *net, struct sk_buff *skb, |
1da177e4c Linux-2.6.12-rc2 |
1235 1236 1237 1238 1239 |
const union sctp_addr *paddr, const union sctp_addr *laddr, struct sctp_transport **transportp) { struct sctp_association *asoc; |
4110cc255 sctp: Make the as... |
1240 |
asoc = __sctp_lookup_association(net, laddr, paddr, transportp); |
b77b7565a sctp: add pr_debu... |
1241 1242 |
if (asoc) goto out; |
1da177e4c Linux-2.6.12-rc2 |
1243 1244 1245 1246 1247 |
/* Further lookup for INIT/INIT-ACK packets. * SCTP Implementors Guide, 2.18 Handling of address * parameters within the INIT or INIT-ACK. */ |
b77b7565a sctp: add pr_debu... |
1248 1249 1250 |
asoc = __sctp_rcv_lookup_harder(net, skb, laddr, transportp); if (asoc) goto out; |
1da177e4c Linux-2.6.12-rc2 |
1251 |
|
b77b7565a sctp: add pr_debu... |
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 |
if (paddr->sa.sa_family == AF_INET) pr_debug("sctp: asoc not found for src:%pI4:%d dst:%pI4:%d ", &laddr->v4.sin_addr, ntohs(laddr->v4.sin_port), &paddr->v4.sin_addr, ntohs(paddr->v4.sin_port)); else pr_debug("sctp: asoc not found for src:%pI6:%d dst:%pI6:%d ", &laddr->v6.sin6_addr, ntohs(laddr->v6.sin6_port), &paddr->v6.sin6_addr, ntohs(paddr->v6.sin6_port)); out: |
1da177e4c Linux-2.6.12-rc2 |
1264 1265 |
return asoc; } |