Merge with Linux 2.5.59.
[linux-2.6/linux-mips.git] / net / sctp / ulpevent.c
blob78d88d00956b5c38327190bde20157538b61436c
1 /* SCTP kernel reference Implementation
2 * Copyright (c) 1999-2000 Cisco, Inc.
3 * Copyright (c) 1999-2001 Motorola, Inc.
4 * Copyright (c) 2001 International Business Machines, Corp.
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 sctp_ulpevent_t 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.
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.
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.
28 * Please send any bug reports or fixes you make to the
29 * email address(es):
30 * lksctp developers <lksctp-developers@lists.sourceforge.net>
32 * Or submit a bug report through the following website:
33 * http://www.sf.net/projects/lksctp
35 * Written or modified by:
36 * Jon Grimm <jgrimm@us.ibm.com>
37 * La Monte H.P. Yarroll <piggy@acm.org>
39 * Any bugs reported given to us we will try to fix... any fixes shared will
40 * be incorporated into the next SCTP release.
43 #include <linux/types.h>
44 #include <linux/skbuff.h>
45 #include <net/sctp/structs.h>
46 #include <net/sctp/sctp.h>
47 #include <net/sctp/sm.h>
49 static void sctp_ulpevent_set_owner_r(struct sk_buff *skb,
50 sctp_association_t *asoc);
51 static void
52 sctp_ulpevent_set_owner(struct sk_buff *skb, const sctp_association_t *asoc);
54 /* Create a new sctp_ulpevent. */
55 sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority)
57 sctp_ulpevent_t *event;
58 struct sk_buff *skb;
60 skb = alloc_skb(size, priority);
61 if (!skb)
62 goto fail;
64 event = (sctp_ulpevent_t *) skb->cb;
65 event = sctp_ulpevent_init(event, skb, msg_flags);
66 if (!event)
67 goto fail_init;
69 event->malloced = 1;
70 return event;
72 fail_init:
73 kfree_skb(event->parent);
75 fail:
76 return NULL;
79 /* Initialize an ULP event from an given skb. */
80 sctp_ulpevent_t *sctp_ulpevent_init(sctp_ulpevent_t *event,
81 struct sk_buff *parent,
82 int msg_flags)
84 memset(event, sizeof(sctp_ulpevent_t), 0x00);
85 event->msg_flags = msg_flags;
86 event->parent = parent;
87 event->malloced = 0;
88 return event;
91 /* Dispose of an event. */
92 void sctp_ulpevent_free(sctp_ulpevent_t *event)
94 if (event->malloced)
95 kfree_skb(event->parent);
98 /* Is this a MSG_NOTIFICATION? */
99 int sctp_ulpevent_is_notification(const sctp_ulpevent_t *event)
101 return event->msg_flags & MSG_NOTIFICATION;
104 /* Create and initialize an SCTP_ASSOC_CHANGE event.
106 * 5.3.1.1 SCTP_ASSOC_CHANGE
108 * Communication notifications inform the ULP that an SCTP association
109 * has either begun or ended. The identifier for a new association is
110 * provided by this notification.
112 * Note: There is no field checking here. If a field is unused it will be
113 * zero'd out.
115 sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
116 __u16 flags,
117 __u16 state,
118 __u16 error,
119 __u16 outbound,
120 __u16 inbound,
121 int priority)
123 sctp_ulpevent_t *event;
124 struct sctp_assoc_change *sac;
126 event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
127 MSG_NOTIFICATION, priority);
128 if (!event)
129 goto fail;
131 sac = (struct sctp_assoc_change *)
132 skb_put(event->parent, sizeof(struct sctp_assoc_change));
134 /* Socket Extensions for SCTP
135 * 5.3.1.1 SCTP_ASSOC_CHANGE
137 * sac_type:
138 * It should be SCTP_ASSOC_CHANGE.
140 sac->sac_type = SCTP_ASSOC_CHANGE;
142 /* Socket Extensions for SCTP
143 * 5.3.1.1 SCTP_ASSOC_CHANGE
145 * sac_state: 32 bits (signed integer)
146 * This field holds one of a number of values that communicate the
147 * event that happened to the association.
149 sac->sac_state = state;
151 /* Socket Extensions for SCTP
152 * 5.3.1.1 SCTP_ASSOC_CHANGE
154 * sac_flags: 16 bits (unsigned integer)
155 * Currently unused.
157 sac->sac_flags = 0;
159 /* Socket Extensions for SCTP
160 * 5.3.1.1 SCTP_ASSOC_CHANGE
162 * sac_length: sizeof (__u32)
163 * This field is the total length of the notification data, including
164 * the notification header.
166 sac->sac_length = sizeof(struct sctp_assoc_change);
168 /* Socket Extensions for SCTP
169 * 5.3.1.1 SCTP_ASSOC_CHANGE
171 * sac_error: 32 bits (signed integer)
173 * If the state was reached due to a error condition (e.g.
174 * COMMUNICATION_LOST) any relevant error information is available in
175 * this field. This corresponds to the protocol error codes defined in
176 * [SCTP].
178 sac->sac_error = error;
180 /* Socket Extensions for SCTP
181 * 5.3.1.1 SCTP_ASSOC_CHANGE
183 * sac_outbound_streams: 16 bits (unsigned integer)
184 * sac_inbound_streams: 16 bits (unsigned integer)
186 * The maximum number of streams allowed in each direction are
187 * available in sac_outbound_streams and sac_inbound streams.
189 sac->sac_outbound_streams = outbound;
190 sac->sac_inbound_streams = inbound;
192 /* Socket Extensions for SCTP
193 * 5.3.1.1 SCTP_ASSOC_CHANGE
195 * sac_assoc_id: sizeof (sctp_assoc_t)
197 * The association id field, holds the identifier for the association.
198 * All notifications for a given association have the same association
199 * identifier. For TCP style socket, this field is ignored.
201 sctp_ulpevent_set_owner(event->parent, asoc);
202 sac->sac_assoc_id = sctp_assoc2id(asoc);
204 return event;
206 fail:
207 return NULL;
210 /* Create and initialize an SCTP_PEER_ADDR_CHANGE event.
212 * Socket Extensions for SCTP - draft-01
213 * 5.3.1.2 SCTP_PEER_ADDR_CHANGE
215 * When a destination address on a multi-homed peer encounters a change
216 * an interface details event is sent.
218 sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
219 const sctp_association_t *asoc,
220 const struct sockaddr_storage *aaddr,
221 int flags,
222 int state,
223 int error,
224 int priority)
226 sctp_ulpevent_t *event;
227 struct sctp_paddr_change *spc;
229 event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change),
230 MSG_NOTIFICATION, priority);
231 if (!event)
232 goto fail;
234 spc = (struct sctp_paddr_change *)
235 skb_put(event->parent, sizeof(struct sctp_paddr_change));
237 /* Sockets API Extensions for SCTP
238 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
240 * spc_type:
242 * It should be SCTP_PEER_ADDR_CHANGE.
244 spc->spc_type = SCTP_PEER_ADDR_CHANGE;
246 /* Sockets API Extensions for SCTP
247 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
249 * spc_length: sizeof (__u32)
251 * This field is the total length of the notification data, including
252 * the notification header.
254 spc->spc_length = sizeof(struct sctp_paddr_change);
256 /* Sockets API Extensions for SCTP
257 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
259 * spc_flags: 16 bits (unsigned integer)
260 * Currently unused.
262 spc->spc_flags = 0;
264 /* Sockets API Extensions for SCTP
265 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
267 * spc_state: 32 bits (signed integer)
269 * This field holds one of a number of values that communicate the
270 * event that happened to the address.
272 spc->spc_state = state;
274 /* Sockets API Extensions for SCTP
275 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
277 * spc_error: 32 bits (signed integer)
279 * If the state was reached due to any error condition (e.g.
280 * ADDRESS_UNREACHABLE) any relevant error information is available in
281 * this field.
283 spc->spc_error = error;
285 /* Socket Extensions for SCTP
286 * 5.3.1.1 SCTP_ASSOC_CHANGE
288 * spc_assoc_id: sizeof (sctp_assoc_t)
290 * The association id field, holds the identifier for the association.
291 * All notifications for a given association have the same association
292 * identifier. For TCP style socket, this field is ignored.
294 sctp_ulpevent_set_owner(event->parent, asoc);
295 spc->spc_assoc_id = sctp_assoc2id(asoc);
297 /* Sockets API Extensions for SCTP
298 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
300 * spc_aaddr: sizeof (struct sockaddr_storage)
302 * The affected address field, holds the remote peer's address that is
303 * encountering the change of state.
305 memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage));
307 return event;
309 fail:
310 return NULL;
313 /* Create and initialize an SCTP_REMOTE_ERROR notification.
315 * Note: This assumes that the chunk->skb->data already points to the
316 * operation error payload.
318 * Socket Extensions for SCTP - draft-01
319 * 5.3.1.3 SCTP_REMOTE_ERROR
321 * A remote peer may send an Operational Error message to its peer.
322 * This message indicates a variety of error conditions on an
323 * association. The entire error TLV as it appears on the wire is
324 * included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP
325 * specification [SCTP] and any extensions for a list of possible
326 * error formats.
328 sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
329 sctp_chunk_t *chunk,
330 __u16 flags,
331 int priority)
333 sctp_ulpevent_t *event;
334 struct sctp_remote_error *sre;
335 struct sk_buff *skb;
336 sctp_errhdr_t *ch;
337 __u16 cause;
338 int elen;
340 ch = (sctp_errhdr_t *)(chunk->skb->data);
341 cause = ch->cause;
342 elen = ntohs(ch->length) - sizeof(sctp_errhdr_t);
344 /* Pull off the ERROR header. */
345 skb_pull(chunk->skb, sizeof(sctp_errhdr_t));
347 /* Copy the skb to a new skb with room for us to prepend
348 * notification with.
350 skb = skb_copy_expand(chunk->skb,
351 sizeof(struct sctp_remote_error), /* headroom */
352 0, /* tailroom */
353 priority);
355 /* Pull off the rest of the cause TLV from the chunk. */
356 skb_pull(chunk->skb, elen);
357 if (!skb)
358 goto fail;
360 /* Embed the event fields inside the cloned skb. */
361 event = (sctp_ulpevent_t *) skb->cb;
362 event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
364 if (!event)
365 goto fail;
367 event->malloced = 1;
368 sre = (struct sctp_remote_error *)
369 skb_push(skb, sizeof(struct sctp_remote_error));
371 /* Trim the buffer to the right length. */
372 skb_trim(skb, sizeof(struct sctp_remote_error) + elen);
374 /* Socket Extensions for SCTP
375 * 5.3.1.3 SCTP_REMOTE_ERROR
377 * sre_type:
378 * It should be SCTP_REMOTE_ERROR.
380 sre->sre_type = SCTP_REMOTE_ERROR;
383 * Socket Extensions for SCTP
384 * 5.3.1.3 SCTP_REMOTE_ERROR
386 * sre_flags: 16 bits (unsigned integer)
387 * Currently unused.
389 sre->sre_flags = 0;
391 /* Socket Extensions for SCTP
392 * 5.3.1.3 SCTP_REMOTE_ERROR
394 * sre_length: sizeof (__u32)
396 * This field is the total length of the notification data,
397 * including the notification header.
399 sre->sre_length = skb->len;
401 /* Socket Extensions for SCTP
402 * 5.3.1.3 SCTP_REMOTE_ERROR
404 * sre_error: 16 bits (unsigned integer)
405 * This value represents one of the Operational Error causes defined in
406 * the SCTP specification, in network byte order.
408 sre->sre_error = cause;
410 /* Socket Extensions for SCTP
411 * 5.3.1.3 SCTP_REMOTE_ERROR
413 * sre_assoc_id: sizeof (sctp_assoc_t)
415 * The association id field, holds the identifier for the association.
416 * All notifications for a given association have the same association
417 * identifier. For TCP style socket, this field is ignored.
419 sctp_ulpevent_set_owner(event->parent, asoc);
420 sre->sre_assoc_id = sctp_assoc2id(asoc);
422 return event;
424 fail:
425 return NULL;
428 /* Create and initialize a SCTP_SEND_FAILED notification.
430 * Socket Extensions for SCTP - draft-01
431 * 5.3.1.4 SCTP_SEND_FAILED
433 sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
434 sctp_chunk_t *chunk,
435 __u16 flags,
436 __u32 error,
437 int priority)
439 sctp_ulpevent_t *event;
440 struct sctp_send_failed *ssf;
441 struct sk_buff *skb;
443 /* Make skb with more room so we can prepend notification. */
444 skb = skb_copy_expand(chunk->skb,
445 sizeof(struct sctp_send_failed), /* headroom */
446 0, /* tailroom */
447 priority);
448 if (!skb)
449 goto fail;
451 /* Pull off the common chunk header and DATA header. */
452 skb_pull(skb, sizeof(sctp_data_chunk_t));
454 /* Embed the event fields inside the cloned skb. */
455 event = (sctp_ulpevent_t *) skb->cb;
456 event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
457 if (!event)
458 goto fail;
460 /* Mark as malloced, even though the constructor was not
461 * called.
463 event->malloced = 1;
465 ssf = (struct sctp_send_failed *)
466 skb_push(skb, sizeof(struct sctp_send_failed));
468 /* Socket Extensions for SCTP
469 * 5.3.1.4 SCTP_SEND_FAILED
471 * ssf_type:
472 * It should be SCTP_SEND_FAILED.
474 ssf->ssf_type = SCTP_SEND_FAILED;
476 /* Socket Extensions for SCTP
477 * 5.3.1.4 SCTP_SEND_FAILED
479 * ssf_flags: 16 bits (unsigned integer)
480 * The flag value will take one of the following values
482 * SCTP_DATA_UNSENT - Indicates that the data was never put on
483 * the wire.
485 * SCTP_DATA_SENT - Indicates that the data was put on the wire.
486 * Note that this does not necessarily mean that the
487 * data was (or was not) successfully delivered.
489 ssf->ssf_flags = flags;
491 /* Socket Extensions for SCTP
492 * 5.3.1.4 SCTP_SEND_FAILED
494 * ssf_length: sizeof (__u32)
495 * This field is the total length of the notification data, including
496 * the notification header.
498 ssf->ssf_length = skb->len;
500 /* Socket Extensions for SCTP
501 * 5.3.1.4 SCTP_SEND_FAILED
503 * ssf_error: 16 bits (unsigned integer)
504 * This value represents the reason why the send failed, and if set,
505 * will be a SCTP protocol error code as defined in [SCTP] section
506 * 3.3.10.
508 ssf->ssf_error = error;
510 /* Socket Extensions for SCTP
511 * 5.3.1.4 SCTP_SEND_FAILED
513 * ssf_info: sizeof (struct sctp_sndrcvinfo)
514 * The original send information associated with the undelivered
515 * message.
517 memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo));
519 /* Socket Extensions for SCTP
520 * 5.3.1.4 SCTP_SEND_FAILED
522 * ssf_assoc_id: sizeof (sctp_assoc_t)
523 * The association id field, sf_assoc_id, holds the identifier for the
524 * association. All notifications for a given association have the
525 * same association identifier. For TCP style socket, this field is
526 * ignored.
528 sctp_ulpevent_set_owner(event->parent, asoc);
529 ssf->ssf_assoc_id = sctp_assoc2id(asoc);
530 return event;
532 fail:
533 return NULL;
536 /* Create and initialize a SCTP_SHUTDOWN_EVENT notification.
538 * Socket Extensions for SCTP - draft-01
539 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
541 sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
542 const sctp_association_t *asoc,
543 __u16 flags,
544 int priority)
546 sctp_ulpevent_t *event;
547 struct sctp_shutdown_event *sse;
549 event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
550 MSG_NOTIFICATION, priority);
551 if (!event)
552 goto fail;
554 sse = (struct sctp_shutdown_event *)
555 skb_put(event->parent, sizeof(struct sctp_shutdown_event));
557 /* Socket Extensions for SCTP
558 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
560 * sse_type
561 * It should be SCTP_SHUTDOWN_EVENT
563 sse->sse_type = SCTP_SHUTDOWN_EVENT;
565 /* Socket Extensions for SCTP
566 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
568 * sse_flags: 16 bits (unsigned integer)
569 * Currently unused.
571 sse->sse_flags = 0;
573 /* Socket Extensions for SCTP
574 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
576 * sse_length: sizeof (__u32)
577 * This field is the total length of the notification data, including
578 * the notification header.
580 sse->sse_length = sizeof(struct sctp_shutdown_event);
582 /* Socket Extensions for SCTP
583 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
585 * sse_assoc_id: sizeof (sctp_assoc_t)
586 * The association id field, holds the identifier for the association.
587 * All notifications for a given association have the same association
588 * identifier. For TCP style socket, this field is ignored.
590 sctp_ulpevent_set_owner(event->parent, asoc);
591 sse->sse_assoc_id = sctp_assoc2id(asoc);
593 return event;
595 fail:
596 return NULL;
599 /* A message has been received. Package this message as a notification
600 * to pass it to the upper layers. Go ahead and calculate the sndrcvinfo
601 * even if filtered out later.
603 * Socket Extensions for SCTP - draft-01
604 * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
606 sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
607 sctp_chunk_t *chunk, int priority)
609 sctp_ulpevent_t *event;
610 struct sctp_sndrcvinfo *info;
611 struct sk_buff *skb;
612 size_t padding, len;
614 /* Clone the original skb, sharing the data. */
615 skb = skb_clone(chunk->skb, priority);
616 if (!skb)
617 goto fail;
619 /* First calculate the padding, so we don't inadvertently
620 * pass up the wrong length to the user.
622 * RFC 2960 - Section 3.2 Chunk Field Descriptions
624 * The total length of a chunk(including Type, Length and Value fields)
625 * MUST be a multiple of 4 bytes. If the length of the chunk is not a
626 * multiple of 4 bytes, the sender MUST pad the chunk with all zero
627 * bytes and this padding is not included in the chunk length field.
628 * The sender should never pad with more than 3 bytes. The receiver
629 * MUST ignore the padding bytes.
631 len = ntohs(chunk->chunk_hdr->length);
632 padding = WORD_ROUND(len) - len;
634 /* Fixup cloned skb with just this chunks data. */
635 skb_trim(skb, chunk->chunk_end - padding - skb->data);
637 /* Set up a destructor to do rwnd accounting. */
638 sctp_ulpevent_set_owner_r(skb, asoc);
640 /* Embed the event fields inside the cloned skb. */
641 event = (sctp_ulpevent_t *) skb->cb;
643 /* Initialize event with flags 0. */
644 event = sctp_ulpevent_init(event, skb, 0);
645 if (!event)
646 goto fail_init;
648 event->malloced = 1;
650 info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo;
652 /* Sockets API Extensions for SCTP
653 * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
655 * sinfo_stream: 16 bits (unsigned integer)
657 * For recvmsg() the SCTP stack places the message's stream number in
658 * this value.
660 info->sinfo_stream = ntohs(chunk->subh.data_hdr->stream);
662 /* Sockets API Extensions for SCTP
663 * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
665 * sinfo_ssn: 16 bits (unsigned integer)
667 * For recvmsg() this value contains the stream sequence number that
668 * the remote endpoint placed in the DATA chunk. For fragmented
669 * messages this is the same number for all deliveries of the message
670 * (if more than one recvmsg() is needed to read the message).
672 info->sinfo_ssn = ntohs(chunk->subh.data_hdr->ssn);
674 /* Sockets API Extensions for SCTP
675 * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
677 * sinfo_ppid: 32 bits (unsigned integer)
679 * In recvmsg() this value is
680 * the same information that was passed by the upper layer in the peer
681 * application. Please note that byte order issues are NOT accounted
682 * for and this information is passed opaquely by the SCTP stack from
683 * one end to the other.
685 info->sinfo_ppid = ntohl(chunk->subh.data_hdr->ppid);
687 /* Sockets API Extensions for SCTP
688 * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
690 * sinfo_flags: 16 bits (unsigned integer)
692 * This field may contain any of the following flags and is composed of
693 * a bitwise OR of these values.
695 * recvmsg() flags:
697 * MSG_UNORDERED - This flag is present when the message was sent
698 * non-ordered.
700 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
701 info->sinfo_flags |= MSG_UNORDERED;
703 /* FIXME: For reassembly, we need to have the fragmentation bits.
704 * This really does not belong in the event structure, but
705 * its difficult to fix everything at the same time. Eventually,
706 * we should create and skb based chunk structure. This structure
707 * storage can be converted to an event. --jgrimm
709 event->chunk_flags = chunk->chunk_hdr->flags;
711 /* With -04 draft, tsn moves into sndrcvinfo. */
712 info->sinfo_tsn = ntohl(chunk->subh.data_hdr->tsn);
714 /* Context is not used on receive. */
715 info->sinfo_context = 0;
717 /* Sockets API Extensions for SCTP
718 * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
720 * sinfo_assoc_id: sizeof (sctp_assoc_t)
722 * The association handle field, sinfo_assoc_id, holds the identifier
723 * for the association announced in the COMMUNICATION_UP notification.
724 * All notifications for a given association have the same identifier.
725 * Ignored for TCP-style sockets.
727 info->sinfo_assoc_id = sctp_assoc2id(asoc);
729 return event;
731 fail_init:
732 kfree_skb(skb);
734 fail:
735 return NULL;
738 /* Return the notification type, assuming this is a notification
739 * event.
741 __u16 sctp_ulpevent_get_notification_type(const sctp_ulpevent_t *event)
743 union sctp_notification *notification;
745 notification = (union sctp_notification *) event->parent->data;
746 return notification->h.sn_type;
749 /* Copy out the sndrcvinfo into a msghdr. */
750 void sctp_ulpevent_read_sndrcvinfo(const sctp_ulpevent_t *event,
751 struct msghdr *msghdr)
753 if (!sctp_ulpevent_is_notification(event)) {
754 put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,
755 sizeof(struct sctp_sndrcvinfo),
756 (void *) &event->sndrcvinfo);
760 /* Do accounting for bytes just read by user. */
761 static void sctp_rcvmsg_rfree(struct sk_buff *skb)
763 sctp_association_t *asoc;
764 sctp_ulpevent_t *event;
765 sctp_chunk_t *sack;
766 struct timer_list *timer;
768 /* Current stack structures assume that the rcv buffer is
769 * per socket. For UDP style sockets this is not true as
770 * multiple associations may be on a single UDP-style socket.
771 * Use the local private area of the skb to track the owning
772 * association.
774 event = (sctp_ulpevent_t *) skb->cb;
775 asoc = event->asoc;
776 if (asoc->rwnd_over) {
777 if (asoc->rwnd_over >= skb->len) {
778 asoc->rwnd_over -= skb->len;
779 } else {
780 asoc->rwnd += (skb->len - asoc->rwnd_over);
781 asoc->rwnd_over = 0;
783 } else {
784 asoc->rwnd += skb->len;
787 SCTP_DEBUG_PRINTK("rwnd increased by %d to (%u, %u) - %u\n",
788 skb->len, asoc->rwnd, asoc->rwnd_over, asoc->a_rwnd);
790 /* Send a window update SACK if the rwnd has increased by at least the
791 * minimum of the association's PMTU and half of the receive buffer.
792 * The algorithm used is similar to the one described in Section 4.2.3.3
793 * of RFC 1122.
795 if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
796 (asoc->rwnd > asoc->a_rwnd) &&
797 ((asoc->rwnd - asoc->a_rwnd) >=
798 min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) {
799 SCTP_DEBUG_PRINTK("Sending window update SACK- rwnd: %u "
800 "a_rwnd: %u\n", asoc->rwnd, asoc->a_rwnd);
801 sack = sctp_make_sack(asoc);
802 if (!sack)
803 goto out;
805 /* Update the last advertised rwnd value. */
806 asoc->a_rwnd = asoc->rwnd;
808 asoc->peer.sack_needed = 0;
809 asoc->peer.next_dup_tsn = 0;
811 sctp_push_outqueue(&asoc->outqueue, sack);
813 /* Stop the SACK timer. */
814 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
815 if (timer_pending(timer) && del_timer(timer))
816 sctp_association_put(asoc);
819 out:
820 sctp_association_put(asoc);
823 /* Charge receive window for bytes recieved. */
824 static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *asoc)
826 sctp_ulpevent_t *event;
828 /* The current stack structures assume that the rcv buffer is
829 * per socket. For UDP-style sockets this is not true as
830 * multiple associations may be on a single UDP-style socket.
831 * We use the local private area of the skb to track the owning
832 * association.
834 sctp_association_hold(asoc);
835 skb->sk = asoc->base.sk;
836 event = (sctp_ulpevent_t *) skb->cb;
837 event->asoc = asoc;
839 skb->destructor = sctp_rcvmsg_rfree;
841 SCTP_ASSERT(asoc->rwnd, "rwnd zero", return);
842 SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return);
843 if (asoc->rwnd >= skb->len) {
844 asoc->rwnd -= skb->len;
845 } else {
846 asoc->rwnd_over = skb->len - asoc->rwnd;
847 asoc->rwnd = 0;
849 SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n",
850 skb->len, asoc->rwnd, asoc->rwnd_over);
853 /* A simple destructor to give up the reference to the association. */
854 static void sctp_ulpevent_rfree(struct sk_buff *skb)
856 sctp_ulpevent_t *event;
858 event = (sctp_ulpevent_t *)skb->cb;
859 sctp_association_put(event->asoc);
862 /* Hold the association in case the msg_name needs read out of
863 * the association.
865 static void sctp_ulpevent_set_owner(struct sk_buff *skb,
866 const sctp_association_t *asoc)
868 sctp_ulpevent_t *event;
870 /* Cast away the const, as we are just wanting to
871 * bump the reference count.
873 sctp_association_hold((sctp_association_t *)asoc);
874 skb->sk = asoc->base.sk;
875 event = (sctp_ulpevent_t *)skb->cb;
876 event->asoc = (sctp_association_t *)asoc;
877 skb->destructor = sctp_ulpevent_rfree;