diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/sctp/ulpevent.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/sctp/ulpevent.c')
-rw-r--r-- | net/sctp/ulpevent.c | 942 |
1 files changed, 942 insertions, 0 deletions
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c new file mode 100644 index 000000000000..17d0ff534735 --- /dev/null +++ b/net/sctp/ulpevent.c | |||
@@ -0,0 +1,942 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * Copyright (c) 2001 Nokia, Inc. | ||
7 | * Copyright (c) 2001 La Monte H.P. Yarroll | ||
8 | * | ||
9 | * These functions manipulate an sctp event. The struct ulpevent is used | ||
10 | * to carry notifications and data to the ULP (sockets). | ||
11 | * The SCTP reference implementation is free software; | ||
12 | * you can redistribute it and/or modify it under the terms of | ||
13 | * the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * The SCTP reference implementation is distributed in the hope that it | ||
18 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
19 | * ************************ | ||
20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | * See the GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with GNU CC; see the file COPYING. If not, write to | ||
25 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
26 | * Boston, MA 02111-1307, USA. | ||
27 | * | ||
28 | * Please send any bug reports or fixes you make to the | ||
29 | * email address(es): | ||
30 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
31 | * | ||
32 | * Or submit a bug report through the following website: | ||
33 | * http://www.sf.net/projects/lksctp | ||
34 | * | ||
35 | * Written or modified by: | ||
36 | * Jon Grimm <jgrimm@us.ibm.com> | ||
37 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
38 | * Ardelle Fan <ardelle.fan@intel.com> | ||
39 | * Sridhar Samudrala <sri@us.ibm.com> | ||
40 | * | ||
41 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
42 | * be incorporated into the next SCTP release. | ||
43 | */ | ||
44 | |||
45 | #include <linux/types.h> | ||
46 | #include <linux/skbuff.h> | ||
47 | #include <net/sctp/structs.h> | ||
48 | #include <net/sctp/sctp.h> | ||
49 | #include <net/sctp/sm.h> | ||
50 | |||
51 | static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | ||
52 | struct sctp_association *asoc); | ||
53 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event); | ||
54 | |||
55 | /* Stub skb destructor. */ | ||
56 | static void sctp_stub_rfree(struct sk_buff *skb) | ||
57 | { | ||
58 | /* WARNING: This function is just a warning not to use the | ||
59 | * skb destructor. If the skb is shared, we may get the destructor | ||
60 | * callback on some processor that does not own the sock_lock. This | ||
61 | * was occuring with PACKET socket applications that were monitoring | ||
62 | * our skbs. We can't take the sock_lock, because we can't risk | ||
63 | * recursing if we do really own the sock lock. Instead, do all | ||
64 | * of our rwnd manipulation while we own the sock_lock outright. | ||
65 | */ | ||
66 | } | ||
67 | |||
68 | /* Initialize an ULP event from an given skb. */ | ||
69 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) | ||
70 | { | ||
71 | memset(event, 0, sizeof(struct sctp_ulpevent)); | ||
72 | event->msg_flags = msg_flags; | ||
73 | } | ||
74 | |||
75 | /* Create a new sctp_ulpevent. */ | ||
76 | SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, | ||
77 | int gfp) | ||
78 | { | ||
79 | struct sctp_ulpevent *event; | ||
80 | struct sk_buff *skb; | ||
81 | |||
82 | skb = alloc_skb(size, gfp); | ||
83 | if (!skb) | ||
84 | goto fail; | ||
85 | |||
86 | event = sctp_skb2event(skb); | ||
87 | sctp_ulpevent_init(event, msg_flags); | ||
88 | |||
89 | return event; | ||
90 | |||
91 | fail: | ||
92 | return NULL; | ||
93 | } | ||
94 | |||
95 | /* Is this a MSG_NOTIFICATION? */ | ||
96 | int sctp_ulpevent_is_notification(const struct sctp_ulpevent *event) | ||
97 | { | ||
98 | return MSG_NOTIFICATION == (event->msg_flags & MSG_NOTIFICATION); | ||
99 | } | ||
100 | |||
101 | /* Hold the association in case the msg_name needs read out of | ||
102 | * the association. | ||
103 | */ | ||
104 | static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event, | ||
105 | const struct sctp_association *asoc) | ||
106 | { | ||
107 | struct sk_buff *skb; | ||
108 | |||
109 | /* Cast away the const, as we are just wanting to | ||
110 | * bump the reference count. | ||
111 | */ | ||
112 | sctp_association_hold((struct sctp_association *)asoc); | ||
113 | skb = sctp_event2skb(event); | ||
114 | skb->sk = asoc->base.sk; | ||
115 | event->asoc = (struct sctp_association *)asoc; | ||
116 | skb->destructor = sctp_stub_rfree; | ||
117 | } | ||
118 | |||
119 | /* A simple destructor to give up the reference to the association. */ | ||
120 | static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) | ||
121 | { | ||
122 | sctp_association_put(event->asoc); | ||
123 | } | ||
124 | |||
125 | /* Create and initialize an SCTP_ASSOC_CHANGE event. | ||
126 | * | ||
127 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
128 | * | ||
129 | * Communication notifications inform the ULP that an SCTP association | ||
130 | * has either begun or ended. The identifier for a new association is | ||
131 | * provided by this notification. | ||
132 | * | ||
133 | * Note: There is no field checking here. If a field is unused it will be | ||
134 | * zero'd out. | ||
135 | */ | ||
136 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | ||
137 | const struct sctp_association *asoc, | ||
138 | __u16 flags, __u16 state, __u16 error, __u16 outbound, | ||
139 | __u16 inbound, int gfp) | ||
140 | { | ||
141 | struct sctp_ulpevent *event; | ||
142 | struct sctp_assoc_change *sac; | ||
143 | struct sk_buff *skb; | ||
144 | |||
145 | event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change), | ||
146 | MSG_NOTIFICATION, gfp); | ||
147 | if (!event) | ||
148 | goto fail; | ||
149 | skb = sctp_event2skb(event); | ||
150 | sac = (struct sctp_assoc_change *) | ||
151 | skb_put(skb, sizeof(struct sctp_assoc_change)); | ||
152 | |||
153 | /* Socket Extensions for SCTP | ||
154 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
155 | * | ||
156 | * sac_type: | ||
157 | * It should be SCTP_ASSOC_CHANGE. | ||
158 | */ | ||
159 | sac->sac_type = SCTP_ASSOC_CHANGE; | ||
160 | |||
161 | /* Socket Extensions for SCTP | ||
162 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
163 | * | ||
164 | * sac_state: 32 bits (signed integer) | ||
165 | * This field holds one of a number of values that communicate the | ||
166 | * event that happened to the association. | ||
167 | */ | ||
168 | sac->sac_state = state; | ||
169 | |||
170 | /* Socket Extensions for SCTP | ||
171 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
172 | * | ||
173 | * sac_flags: 16 bits (unsigned integer) | ||
174 | * Currently unused. | ||
175 | */ | ||
176 | sac->sac_flags = 0; | ||
177 | |||
178 | /* Socket Extensions for SCTP | ||
179 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
180 | * | ||
181 | * sac_length: sizeof (__u32) | ||
182 | * This field is the total length of the notification data, including | ||
183 | * the notification header. | ||
184 | */ | ||
185 | sac->sac_length = sizeof(struct sctp_assoc_change); | ||
186 | |||
187 | /* Socket Extensions for SCTP | ||
188 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
189 | * | ||
190 | * sac_error: 32 bits (signed integer) | ||
191 | * | ||
192 | * If the state was reached due to a error condition (e.g. | ||
193 | * COMMUNICATION_LOST) any relevant error information is available in | ||
194 | * this field. This corresponds to the protocol error codes defined in | ||
195 | * [SCTP]. | ||
196 | */ | ||
197 | sac->sac_error = error; | ||
198 | |||
199 | /* Socket Extensions for SCTP | ||
200 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
201 | * | ||
202 | * sac_outbound_streams: 16 bits (unsigned integer) | ||
203 | * sac_inbound_streams: 16 bits (unsigned integer) | ||
204 | * | ||
205 | * The maximum number of streams allowed in each direction are | ||
206 | * available in sac_outbound_streams and sac_inbound streams. | ||
207 | */ | ||
208 | sac->sac_outbound_streams = outbound; | ||
209 | sac->sac_inbound_streams = inbound; | ||
210 | |||
211 | /* Socket Extensions for SCTP | ||
212 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
213 | * | ||
214 | * sac_assoc_id: sizeof (sctp_assoc_t) | ||
215 | * | ||
216 | * The association id field, holds the identifier for the association. | ||
217 | * All notifications for a given association have the same association | ||
218 | * identifier. For TCP style socket, this field is ignored. | ||
219 | */ | ||
220 | sctp_ulpevent_set_owner(event, asoc); | ||
221 | sac->sac_assoc_id = sctp_assoc2id(asoc); | ||
222 | |||
223 | return event; | ||
224 | |||
225 | fail: | ||
226 | return NULL; | ||
227 | } | ||
228 | |||
229 | /* Create and initialize an SCTP_PEER_ADDR_CHANGE event. | ||
230 | * | ||
231 | * Socket Extensions for SCTP - draft-01 | ||
232 | * 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
233 | * | ||
234 | * When a destination address on a multi-homed peer encounters a change | ||
235 | * an interface details event is sent. | ||
236 | */ | ||
237 | struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( | ||
238 | const struct sctp_association *asoc, | ||
239 | const struct sockaddr_storage *aaddr, | ||
240 | int flags, int state, int error, int gfp) | ||
241 | { | ||
242 | struct sctp_ulpevent *event; | ||
243 | struct sctp_paddr_change *spc; | ||
244 | struct sk_buff *skb; | ||
245 | |||
246 | event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change), | ||
247 | MSG_NOTIFICATION, gfp); | ||
248 | if (!event) | ||
249 | goto fail; | ||
250 | |||
251 | skb = sctp_event2skb(event); | ||
252 | spc = (struct sctp_paddr_change *) | ||
253 | skb_put(skb, sizeof(struct sctp_paddr_change)); | ||
254 | |||
255 | /* Sockets API Extensions for SCTP | ||
256 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
257 | * | ||
258 | * spc_type: | ||
259 | * | ||
260 | * It should be SCTP_PEER_ADDR_CHANGE. | ||
261 | */ | ||
262 | spc->spc_type = SCTP_PEER_ADDR_CHANGE; | ||
263 | |||
264 | /* Sockets API Extensions for SCTP | ||
265 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
266 | * | ||
267 | * spc_length: sizeof (__u32) | ||
268 | * | ||
269 | * This field is the total length of the notification data, including | ||
270 | * the notification header. | ||
271 | */ | ||
272 | spc->spc_length = sizeof(struct sctp_paddr_change); | ||
273 | |||
274 | /* Sockets API Extensions for SCTP | ||
275 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
276 | * | ||
277 | * spc_flags: 16 bits (unsigned integer) | ||
278 | * Currently unused. | ||
279 | */ | ||
280 | spc->spc_flags = 0; | ||
281 | |||
282 | /* Sockets API Extensions for SCTP | ||
283 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
284 | * | ||
285 | * spc_state: 32 bits (signed integer) | ||
286 | * | ||
287 | * This field holds one of a number of values that communicate the | ||
288 | * event that happened to the address. | ||
289 | */ | ||
290 | spc->spc_state = state; | ||
291 | |||
292 | /* Sockets API Extensions for SCTP | ||
293 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
294 | * | ||
295 | * spc_error: 32 bits (signed integer) | ||
296 | * | ||
297 | * If the state was reached due to any error condition (e.g. | ||
298 | * ADDRESS_UNREACHABLE) any relevant error information is available in | ||
299 | * this field. | ||
300 | */ | ||
301 | spc->spc_error = error; | ||
302 | |||
303 | /* Socket Extensions for SCTP | ||
304 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
305 | * | ||
306 | * spc_assoc_id: sizeof (sctp_assoc_t) | ||
307 | * | ||
308 | * The association id field, holds the identifier for the association. | ||
309 | * All notifications for a given association have the same association | ||
310 | * identifier. For TCP style socket, this field is ignored. | ||
311 | */ | ||
312 | sctp_ulpevent_set_owner(event, asoc); | ||
313 | spc->spc_assoc_id = sctp_assoc2id(asoc); | ||
314 | |||
315 | /* Sockets API Extensions for SCTP | ||
316 | * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
317 | * | ||
318 | * spc_aaddr: sizeof (struct sockaddr_storage) | ||
319 | * | ||
320 | * The affected address field, holds the remote peer's address that is | ||
321 | * encountering the change of state. | ||
322 | */ | ||
323 | memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage)); | ||
324 | |||
325 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | ||
326 | sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map( | ||
327 | sctp_sk(asoc->base.sk), | ||
328 | (union sctp_addr *)&spc->spc_aaddr); | ||
329 | |||
330 | return event; | ||
331 | |||
332 | fail: | ||
333 | return NULL; | ||
334 | } | ||
335 | |||
336 | /* Create and initialize an SCTP_REMOTE_ERROR notification. | ||
337 | * | ||
338 | * Note: This assumes that the chunk->skb->data already points to the | ||
339 | * operation error payload. | ||
340 | * | ||
341 | * Socket Extensions for SCTP - draft-01 | ||
342 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
343 | * | ||
344 | * A remote peer may send an Operational Error message to its peer. | ||
345 | * This message indicates a variety of error conditions on an | ||
346 | * association. The entire error TLV as it appears on the wire is | ||
347 | * included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP | ||
348 | * specification [SCTP] and any extensions for a list of possible | ||
349 | * error formats. | ||
350 | */ | ||
351 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | ||
352 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | ||
353 | __u16 flags, int gfp) | ||
354 | { | ||
355 | struct sctp_ulpevent *event; | ||
356 | struct sctp_remote_error *sre; | ||
357 | struct sk_buff *skb; | ||
358 | sctp_errhdr_t *ch; | ||
359 | __u16 cause; | ||
360 | int elen; | ||
361 | |||
362 | ch = (sctp_errhdr_t *)(chunk->skb->data); | ||
363 | cause = ch->cause; | ||
364 | elen = WORD_ROUND(ntohs(ch->length)) - sizeof(sctp_errhdr_t); | ||
365 | |||
366 | /* Pull off the ERROR header. */ | ||
367 | skb_pull(chunk->skb, sizeof(sctp_errhdr_t)); | ||
368 | |||
369 | /* Copy the skb to a new skb with room for us to prepend | ||
370 | * notification with. | ||
371 | */ | ||
372 | skb = skb_copy_expand(chunk->skb, sizeof(struct sctp_remote_error), | ||
373 | 0, gfp); | ||
374 | |||
375 | /* Pull off the rest of the cause TLV from the chunk. */ | ||
376 | skb_pull(chunk->skb, elen); | ||
377 | if (!skb) | ||
378 | goto fail; | ||
379 | |||
380 | /* Embed the event fields inside the cloned skb. */ | ||
381 | event = sctp_skb2event(skb); | ||
382 | sctp_ulpevent_init(event, MSG_NOTIFICATION); | ||
383 | |||
384 | sre = (struct sctp_remote_error *) | ||
385 | skb_push(skb, sizeof(struct sctp_remote_error)); | ||
386 | |||
387 | /* Trim the buffer to the right length. */ | ||
388 | skb_trim(skb, sizeof(struct sctp_remote_error) + elen); | ||
389 | |||
390 | /* Socket Extensions for SCTP | ||
391 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
392 | * | ||
393 | * sre_type: | ||
394 | * It should be SCTP_REMOTE_ERROR. | ||
395 | */ | ||
396 | sre->sre_type = SCTP_REMOTE_ERROR; | ||
397 | |||
398 | /* | ||
399 | * Socket Extensions for SCTP | ||
400 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
401 | * | ||
402 | * sre_flags: 16 bits (unsigned integer) | ||
403 | * Currently unused. | ||
404 | */ | ||
405 | sre->sre_flags = 0; | ||
406 | |||
407 | /* Socket Extensions for SCTP | ||
408 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
409 | * | ||
410 | * sre_length: sizeof (__u32) | ||
411 | * | ||
412 | * This field is the total length of the notification data, | ||
413 | * including the notification header. | ||
414 | */ | ||
415 | sre->sre_length = skb->len; | ||
416 | |||
417 | /* Socket Extensions for SCTP | ||
418 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
419 | * | ||
420 | * sre_error: 16 bits (unsigned integer) | ||
421 | * This value represents one of the Operational Error causes defined in | ||
422 | * the SCTP specification, in network byte order. | ||
423 | */ | ||
424 | sre->sre_error = cause; | ||
425 | |||
426 | /* Socket Extensions for SCTP | ||
427 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
428 | * | ||
429 | * sre_assoc_id: sizeof (sctp_assoc_t) | ||
430 | * | ||
431 | * The association id field, holds the identifier for the association. | ||
432 | * All notifications for a given association have the same association | ||
433 | * identifier. For TCP style socket, this field is ignored. | ||
434 | */ | ||
435 | sctp_ulpevent_set_owner(event, asoc); | ||
436 | sre->sre_assoc_id = sctp_assoc2id(asoc); | ||
437 | |||
438 | return event; | ||
439 | |||
440 | fail: | ||
441 | return NULL; | ||
442 | } | ||
443 | |||
444 | /* Create and initialize a SCTP_SEND_FAILED notification. | ||
445 | * | ||
446 | * Socket Extensions for SCTP - draft-01 | ||
447 | * 5.3.1.4 SCTP_SEND_FAILED | ||
448 | */ | ||
449 | struct sctp_ulpevent *sctp_ulpevent_make_send_failed( | ||
450 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | ||
451 | __u16 flags, __u32 error, int gfp) | ||
452 | { | ||
453 | struct sctp_ulpevent *event; | ||
454 | struct sctp_send_failed *ssf; | ||
455 | struct sk_buff *skb; | ||
456 | |||
457 | /* Pull off any padding. */ | ||
458 | int len = ntohs(chunk->chunk_hdr->length); | ||
459 | |||
460 | /* Make skb with more room so we can prepend notification. */ | ||
461 | skb = skb_copy_expand(chunk->skb, | ||
462 | sizeof(struct sctp_send_failed), /* headroom */ | ||
463 | 0, /* tailroom */ | ||
464 | gfp); | ||
465 | if (!skb) | ||
466 | goto fail; | ||
467 | |||
468 | /* Pull off the common chunk header and DATA header. */ | ||
469 | skb_pull(skb, sizeof(struct sctp_data_chunk)); | ||
470 | len -= sizeof(struct sctp_data_chunk); | ||
471 | |||
472 | /* Embed the event fields inside the cloned skb. */ | ||
473 | event = sctp_skb2event(skb); | ||
474 | sctp_ulpevent_init(event, MSG_NOTIFICATION); | ||
475 | |||
476 | ssf = (struct sctp_send_failed *) | ||
477 | skb_push(skb, sizeof(struct sctp_send_failed)); | ||
478 | |||
479 | /* Socket Extensions for SCTP | ||
480 | * 5.3.1.4 SCTP_SEND_FAILED | ||
481 | * | ||
482 | * ssf_type: | ||
483 | * It should be SCTP_SEND_FAILED. | ||
484 | */ | ||
485 | ssf->ssf_type = SCTP_SEND_FAILED; | ||
486 | |||
487 | /* Socket Extensions for SCTP | ||
488 | * 5.3.1.4 SCTP_SEND_FAILED | ||
489 | * | ||
490 | * ssf_flags: 16 bits (unsigned integer) | ||
491 | * The flag value will take one of the following values | ||
492 | * | ||
493 | * SCTP_DATA_UNSENT - Indicates that the data was never put on | ||
494 | * the wire. | ||
495 | * | ||
496 | * SCTP_DATA_SENT - Indicates that the data was put on the wire. | ||
497 | * Note that this does not necessarily mean that the | ||
498 | * data was (or was not) successfully delivered. | ||
499 | */ | ||
500 | ssf->ssf_flags = flags; | ||
501 | |||
502 | /* Socket Extensions for SCTP | ||
503 | * 5.3.1.4 SCTP_SEND_FAILED | ||
504 | * | ||
505 | * ssf_length: sizeof (__u32) | ||
506 | * This field is the total length of the notification data, including | ||
507 | * the notification header. | ||
508 | */ | ||
509 | ssf->ssf_length = sizeof(struct sctp_send_failed) + len; | ||
510 | skb_trim(skb, ssf->ssf_length); | ||
511 | |||
512 | /* Socket Extensions for SCTP | ||
513 | * 5.3.1.4 SCTP_SEND_FAILED | ||
514 | * | ||
515 | * ssf_error: 16 bits (unsigned integer) | ||
516 | * This value represents the reason why the send failed, and if set, | ||
517 | * will be a SCTP protocol error code as defined in [SCTP] section | ||
518 | * 3.3.10. | ||
519 | */ | ||
520 | ssf->ssf_error = error; | ||
521 | |||
522 | /* Socket Extensions for SCTP | ||
523 | * 5.3.1.4 SCTP_SEND_FAILED | ||
524 | * | ||
525 | * ssf_info: sizeof (struct sctp_sndrcvinfo) | ||
526 | * The original send information associated with the undelivered | ||
527 | * message. | ||
528 | */ | ||
529 | memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo)); | ||
530 | |||
531 | /* Per TSVWG discussion with Randy. Allow the application to | ||
532 | * ressemble a fragmented message. | ||
533 | */ | ||
534 | ssf->ssf_info.sinfo_flags = chunk->chunk_hdr->flags; | ||
535 | |||
536 | /* Socket Extensions for SCTP | ||
537 | * 5.3.1.4 SCTP_SEND_FAILED | ||
538 | * | ||
539 | * ssf_assoc_id: sizeof (sctp_assoc_t) | ||
540 | * The association id field, sf_assoc_id, holds the identifier for the | ||
541 | * association. All notifications for a given association have the | ||
542 | * same association identifier. For TCP style socket, this field is | ||
543 | * ignored. | ||
544 | */ | ||
545 | sctp_ulpevent_set_owner(event, asoc); | ||
546 | ssf->ssf_assoc_id = sctp_assoc2id(asoc); | ||
547 | return event; | ||
548 | |||
549 | fail: | ||
550 | return NULL; | ||
551 | } | ||
552 | |||
553 | /* Create and initialize a SCTP_SHUTDOWN_EVENT notification. | ||
554 | * | ||
555 | * Socket Extensions for SCTP - draft-01 | ||
556 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
557 | */ | ||
558 | struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( | ||
559 | const struct sctp_association *asoc, | ||
560 | __u16 flags, int gfp) | ||
561 | { | ||
562 | struct sctp_ulpevent *event; | ||
563 | struct sctp_shutdown_event *sse; | ||
564 | struct sk_buff *skb; | ||
565 | |||
566 | event = sctp_ulpevent_new(sizeof(struct sctp_shutdown_event), | ||
567 | MSG_NOTIFICATION, gfp); | ||
568 | if (!event) | ||
569 | goto fail; | ||
570 | |||
571 | skb = sctp_event2skb(event); | ||
572 | sse = (struct sctp_shutdown_event *) | ||
573 | skb_put(skb, sizeof(struct sctp_shutdown_event)); | ||
574 | |||
575 | /* Socket Extensions for SCTP | ||
576 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
577 | * | ||
578 | * sse_type | ||
579 | * It should be SCTP_SHUTDOWN_EVENT | ||
580 | */ | ||
581 | sse->sse_type = SCTP_SHUTDOWN_EVENT; | ||
582 | |||
583 | /* Socket Extensions for SCTP | ||
584 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
585 | * | ||
586 | * sse_flags: 16 bits (unsigned integer) | ||
587 | * Currently unused. | ||
588 | */ | ||
589 | sse->sse_flags = 0; | ||
590 | |||
591 | /* Socket Extensions for SCTP | ||
592 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
593 | * | ||
594 | * sse_length: sizeof (__u32) | ||
595 | * This field is the total length of the notification data, including | ||
596 | * the notification header. | ||
597 | */ | ||
598 | sse->sse_length = sizeof(struct sctp_shutdown_event); | ||
599 | |||
600 | /* Socket Extensions for SCTP | ||
601 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
602 | * | ||
603 | * sse_assoc_id: sizeof (sctp_assoc_t) | ||
604 | * The association id field, holds the identifier for the association. | ||
605 | * All notifications for a given association have the same association | ||
606 | * identifier. For TCP style socket, this field is ignored. | ||
607 | */ | ||
608 | sctp_ulpevent_set_owner(event, asoc); | ||
609 | sse->sse_assoc_id = sctp_assoc2id(asoc); | ||
610 | |||
611 | return event; | ||
612 | |||
613 | fail: | ||
614 | return NULL; | ||
615 | } | ||
616 | |||
617 | /* Create and initialize a SCTP_ADAPTION_INDICATION notification. | ||
618 | * | ||
619 | * Socket Extensions for SCTP | ||
620 | * 5.3.1.6 SCTP_ADAPTION_INDICATION | ||
621 | */ | ||
622 | struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication( | ||
623 | const struct sctp_association *asoc, int gfp) | ||
624 | { | ||
625 | struct sctp_ulpevent *event; | ||
626 | struct sctp_adaption_event *sai; | ||
627 | struct sk_buff *skb; | ||
628 | |||
629 | event = sctp_ulpevent_new(sizeof(struct sctp_adaption_event), | ||
630 | MSG_NOTIFICATION, gfp); | ||
631 | if (!event) | ||
632 | goto fail; | ||
633 | |||
634 | skb = sctp_event2skb(event); | ||
635 | sai = (struct sctp_adaption_event *) | ||
636 | skb_put(skb, sizeof(struct sctp_adaption_event)); | ||
637 | |||
638 | sai->sai_type = SCTP_ADAPTION_INDICATION; | ||
639 | sai->sai_flags = 0; | ||
640 | sai->sai_length = sizeof(struct sctp_adaption_event); | ||
641 | sai->sai_adaption_ind = asoc->peer.adaption_ind; | ||
642 | sctp_ulpevent_set_owner(event, asoc); | ||
643 | sai->sai_assoc_id = sctp_assoc2id(asoc); | ||
644 | |||
645 | return event; | ||
646 | |||
647 | fail: | ||
648 | return NULL; | ||
649 | } | ||
650 | |||
651 | /* A message has been received. Package this message as a notification | ||
652 | * to pass it to the upper layers. Go ahead and calculate the sndrcvinfo | ||
653 | * even if filtered out later. | ||
654 | * | ||
655 | * Socket Extensions for SCTP | ||
656 | * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) | ||
657 | */ | ||
658 | struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | ||
659 | struct sctp_chunk *chunk, | ||
660 | int gfp) | ||
661 | { | ||
662 | struct sctp_ulpevent *event = NULL; | ||
663 | struct sk_buff *skb; | ||
664 | size_t padding, len; | ||
665 | |||
666 | /* Clone the original skb, sharing the data. */ | ||
667 | skb = skb_clone(chunk->skb, gfp); | ||
668 | if (!skb) | ||
669 | goto fail; | ||
670 | |||
671 | /* First calculate the padding, so we don't inadvertently | ||
672 | * pass up the wrong length to the user. | ||
673 | * | ||
674 | * RFC 2960 - Section 3.2 Chunk Field Descriptions | ||
675 | * | ||
676 | * The total length of a chunk(including Type, Length and Value fields) | ||
677 | * MUST be a multiple of 4 bytes. If the length of the chunk is not a | ||
678 | * multiple of 4 bytes, the sender MUST pad the chunk with all zero | ||
679 | * bytes and this padding is not included in the chunk length field. | ||
680 | * The sender should never pad with more than 3 bytes. The receiver | ||
681 | * MUST ignore the padding bytes. | ||
682 | */ | ||
683 | len = ntohs(chunk->chunk_hdr->length); | ||
684 | padding = WORD_ROUND(len) - len; | ||
685 | |||
686 | /* Fixup cloned skb with just this chunks data. */ | ||
687 | skb_trim(skb, chunk->chunk_end - padding - skb->data); | ||
688 | |||
689 | /* Embed the event fields inside the cloned skb. */ | ||
690 | event = sctp_skb2event(skb); | ||
691 | |||
692 | /* Initialize event with flags 0. */ | ||
693 | sctp_ulpevent_init(event, 0); | ||
694 | |||
695 | sctp_ulpevent_receive_data(event, asoc); | ||
696 | |||
697 | event->stream = ntohs(chunk->subh.data_hdr->stream); | ||
698 | event->ssn = ntohs(chunk->subh.data_hdr->ssn); | ||
699 | event->ppid = chunk->subh.data_hdr->ppid; | ||
700 | if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { | ||
701 | event->flags |= MSG_UNORDERED; | ||
702 | event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); | ||
703 | } | ||
704 | event->tsn = ntohl(chunk->subh.data_hdr->tsn); | ||
705 | event->msg_flags |= chunk->chunk_hdr->flags; | ||
706 | event->iif = sctp_chunk_iif(chunk); | ||
707 | |||
708 | fail: | ||
709 | return event; | ||
710 | } | ||
711 | |||
712 | /* Create a partial delivery related event. | ||
713 | * | ||
714 | * 5.3.1.7 SCTP_PARTIAL_DELIVERY_EVENT | ||
715 | * | ||
716 | * When a receiver is engaged in a partial delivery of a | ||
717 | * message this notification will be used to indicate | ||
718 | * various events. | ||
719 | */ | ||
720 | struct sctp_ulpevent *sctp_ulpevent_make_pdapi( | ||
721 | const struct sctp_association *asoc, __u32 indication, int gfp) | ||
722 | { | ||
723 | struct sctp_ulpevent *event; | ||
724 | struct sctp_pdapi_event *pd; | ||
725 | struct sk_buff *skb; | ||
726 | |||
727 | event = sctp_ulpevent_new(sizeof(struct sctp_pdapi_event), | ||
728 | MSG_NOTIFICATION, gfp); | ||
729 | if (!event) | ||
730 | goto fail; | ||
731 | |||
732 | skb = sctp_event2skb(event); | ||
733 | pd = (struct sctp_pdapi_event *) | ||
734 | skb_put(skb, sizeof(struct sctp_pdapi_event)); | ||
735 | |||
736 | /* pdapi_type | ||
737 | * It should be SCTP_PARTIAL_DELIVERY_EVENT | ||
738 | * | ||
739 | * pdapi_flags: 16 bits (unsigned integer) | ||
740 | * Currently unused. | ||
741 | */ | ||
742 | pd->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; | ||
743 | pd->pdapi_flags = 0; | ||
744 | |||
745 | /* pdapi_length: 32 bits (unsigned integer) | ||
746 | * | ||
747 | * This field is the total length of the notification data, including | ||
748 | * the notification header. It will generally be sizeof (struct | ||
749 | * sctp_pdapi_event). | ||
750 | */ | ||
751 | pd->pdapi_length = sizeof(struct sctp_pdapi_event); | ||
752 | |||
753 | /* pdapi_indication: 32 bits (unsigned integer) | ||
754 | * | ||
755 | * This field holds the indication being sent to the application. | ||
756 | */ | ||
757 | pd->pdapi_indication = indication; | ||
758 | |||
759 | /* pdapi_assoc_id: sizeof (sctp_assoc_t) | ||
760 | * | ||
761 | * The association id field, holds the identifier for the association. | ||
762 | */ | ||
763 | sctp_ulpevent_set_owner(event, asoc); | ||
764 | pd->pdapi_assoc_id = sctp_assoc2id(asoc); | ||
765 | |||
766 | return event; | ||
767 | fail: | ||
768 | return NULL; | ||
769 | } | ||
770 | |||
771 | /* Return the notification type, assuming this is a notification | ||
772 | * event. | ||
773 | */ | ||
774 | __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event) | ||
775 | { | ||
776 | union sctp_notification *notification; | ||
777 | struct sk_buff *skb; | ||
778 | |||
779 | skb = sctp_event2skb((struct sctp_ulpevent *)event); | ||
780 | notification = (union sctp_notification *) skb->data; | ||
781 | return notification->sn_header.sn_type; | ||
782 | } | ||
783 | |||
784 | /* Copy out the sndrcvinfo into a msghdr. */ | ||
785 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | ||
786 | struct msghdr *msghdr) | ||
787 | { | ||
788 | struct sctp_sndrcvinfo sinfo; | ||
789 | |||
790 | if (sctp_ulpevent_is_notification(event)) | ||
791 | return; | ||
792 | |||
793 | /* Sockets API Extensions for SCTP | ||
794 | * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) | ||
795 | * | ||
796 | * sinfo_stream: 16 bits (unsigned integer) | ||
797 | * | ||
798 | * For recvmsg() the SCTP stack places the message's stream number in | ||
799 | * this value. | ||
800 | */ | ||
801 | sinfo.sinfo_stream = event->stream; | ||
802 | /* sinfo_ssn: 16 bits (unsigned integer) | ||
803 | * | ||
804 | * For recvmsg() this value contains the stream sequence number that | ||
805 | * the remote endpoint placed in the DATA chunk. For fragmented | ||
806 | * messages this is the same number for all deliveries of the message | ||
807 | * (if more than one recvmsg() is needed to read the message). | ||
808 | */ | ||
809 | sinfo.sinfo_ssn = event->ssn; | ||
810 | /* sinfo_ppid: 32 bits (unsigned integer) | ||
811 | * | ||
812 | * In recvmsg() this value is | ||
813 | * the same information that was passed by the upper layer in the peer | ||
814 | * application. Please note that byte order issues are NOT accounted | ||
815 | * for and this information is passed opaquely by the SCTP stack from | ||
816 | * one end to the other. | ||
817 | */ | ||
818 | sinfo.sinfo_ppid = event->ppid; | ||
819 | /* sinfo_flags: 16 bits (unsigned integer) | ||
820 | * | ||
821 | * This field may contain any of the following flags and is composed of | ||
822 | * a bitwise OR of these values. | ||
823 | * | ||
824 | * recvmsg() flags: | ||
825 | * | ||
826 | * MSG_UNORDERED - This flag is present when the message was sent | ||
827 | * non-ordered. | ||
828 | */ | ||
829 | sinfo.sinfo_flags = event->flags; | ||
830 | /* sinfo_tsn: 32 bit (unsigned integer) | ||
831 | * | ||
832 | * For the receiving side, this field holds a TSN that was | ||
833 | * assigned to one of the SCTP Data Chunks. | ||
834 | */ | ||
835 | sinfo.sinfo_tsn = event->tsn; | ||
836 | /* sinfo_cumtsn: 32 bit (unsigned integer) | ||
837 | * | ||
838 | * This field will hold the current cumulative TSN as | ||
839 | * known by the underlying SCTP layer. Note this field is | ||
840 | * ignored when sending and only valid for a receive | ||
841 | * operation when sinfo_flags are set to MSG_UNORDERED. | ||
842 | */ | ||
843 | sinfo.sinfo_cumtsn = event->cumtsn; | ||
844 | /* sinfo_assoc_id: sizeof (sctp_assoc_t) | ||
845 | * | ||
846 | * The association handle field, sinfo_assoc_id, holds the identifier | ||
847 | * for the association announced in the COMMUNICATION_UP notification. | ||
848 | * All notifications for a given association have the same identifier. | ||
849 | * Ignored for one-to-one style sockets. | ||
850 | */ | ||
851 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); | ||
852 | |||
853 | /* These fields are not used while receiving. */ | ||
854 | sinfo.sinfo_context = 0; | ||
855 | sinfo.sinfo_timetolive = 0; | ||
856 | |||
857 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, | ||
858 | sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); | ||
859 | } | ||
860 | |||
861 | /* Do accounting for bytes received and hold a reference to the association | ||
862 | * for each skb. | ||
863 | */ | ||
864 | static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | ||
865 | struct sctp_association *asoc) | ||
866 | { | ||
867 | struct sk_buff *skb, *frag; | ||
868 | |||
869 | skb = sctp_event2skb(event); | ||
870 | /* Set the owner and charge rwnd for bytes received. */ | ||
871 | sctp_ulpevent_set_owner(event, asoc); | ||
872 | sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb)); | ||
873 | |||
874 | if (!skb->data_len) | ||
875 | return; | ||
876 | |||
877 | /* Note: Not clearing the entire event struct as this is just a | ||
878 | * fragment of the real event. However, we still need to do rwnd | ||
879 | * accounting. | ||
880 | * In general, the skb passed from IP can have only 1 level of | ||
881 | * fragments. But we allow multiple levels of fragments. | ||
882 | */ | ||
883 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | ||
884 | sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); | ||
885 | } | ||
886 | } | ||
887 | |||
888 | /* Do accounting for bytes just read by user and release the references to | ||
889 | * the association. | ||
890 | */ | ||
891 | static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | ||
892 | { | ||
893 | struct sk_buff *skb, *frag; | ||
894 | |||
895 | /* Current stack structures assume that the rcv buffer is | ||
896 | * per socket. For UDP style sockets this is not true as | ||
897 | * multiple associations may be on a single UDP-style socket. | ||
898 | * Use the local private area of the skb to track the owning | ||
899 | * association. | ||
900 | */ | ||
901 | |||
902 | skb = sctp_event2skb(event); | ||
903 | sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb)); | ||
904 | |||
905 | if (!skb->data_len) | ||
906 | goto done; | ||
907 | |||
908 | /* Don't forget the fragments. */ | ||
909 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | ||
910 | /* NOTE: skb_shinfos are recursive. Although IP returns | ||
911 | * skb's with only 1 level of fragments, SCTP reassembly can | ||
912 | * increase the levels. | ||
913 | */ | ||
914 | sctp_ulpevent_release_data(sctp_skb2event(frag)); | ||
915 | } | ||
916 | |||
917 | done: | ||
918 | sctp_ulpevent_release_owner(event); | ||
919 | } | ||
920 | |||
921 | /* Free a ulpevent that has an owner. It includes releasing the reference | ||
922 | * to the owner, updating the rwnd in case of a DATA event and freeing the | ||
923 | * skb. | ||
924 | * See comments in sctp_stub_rfree(). | ||
925 | */ | ||
926 | void sctp_ulpevent_free(struct sctp_ulpevent *event) | ||
927 | { | ||
928 | if (sctp_ulpevent_is_notification(event)) | ||
929 | sctp_ulpevent_release_owner(event); | ||
930 | else | ||
931 | sctp_ulpevent_release_data(event); | ||
932 | |||
933 | kfree_skb(sctp_event2skb(event)); | ||
934 | } | ||
935 | |||
936 | /* Purge the skb lists holding ulpevents. */ | ||
937 | void sctp_queue_purge_ulpevents(struct sk_buff_head *list) | ||
938 | { | ||
939 | struct sk_buff *skb; | ||
940 | while ((skb = skb_dequeue(list)) != NULL) | ||
941 | sctp_ulpevent_free(sctp_skb2event(skb)); | ||
942 | } | ||