diff options
-rw-r--r-- | net/sctp/ulpevent.c | 122 |
1 files changed, 15 insertions, 107 deletions
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 85c64658bd0b..b6842fdb53d4 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -366,9 +366,10 @@ fail: | |||
366 | * specification [SCTP] and any extensions for a list of possible | 366 | * specification [SCTP] and any extensions for a list of possible |
367 | * error formats. | 367 | * error formats. |
368 | */ | 368 | */ |
369 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | 369 | struct sctp_ulpevent * |
370 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | 370 | sctp_ulpevent_make_remote_error(const struct sctp_association *asoc, |
371 | __u16 flags, gfp_t gfp) | 371 | struct sctp_chunk *chunk, __u16 flags, |
372 | gfp_t gfp) | ||
372 | { | 373 | { |
373 | struct sctp_ulpevent *event; | 374 | struct sctp_ulpevent *event; |
374 | struct sctp_remote_error *sre; | 375 | struct sctp_remote_error *sre; |
@@ -387,8 +388,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | |||
387 | /* Copy the skb to a new skb with room for us to prepend | 388 | /* Copy the skb to a new skb with room for us to prepend |
388 | * notification with. | 389 | * notification with. |
389 | */ | 390 | */ |
390 | skb = skb_copy_expand(chunk->skb, sizeof(struct sctp_remote_error), | 391 | skb = skb_copy_expand(chunk->skb, sizeof(*sre), 0, gfp); |
391 | 0, gfp); | ||
392 | 392 | ||
393 | /* Pull off the rest of the cause TLV from the chunk. */ | 393 | /* Pull off the rest of the cause TLV from the chunk. */ |
394 | skb_pull(chunk->skb, elen); | 394 | skb_pull(chunk->skb, elen); |
@@ -399,62 +399,21 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | |||
399 | event = sctp_skb2event(skb); | 399 | event = sctp_skb2event(skb); |
400 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); | 400 | sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); |
401 | 401 | ||
402 | sre = (struct sctp_remote_error *) | 402 | sre = (struct sctp_remote_error *) skb_push(skb, sizeof(*sre)); |
403 | skb_push(skb, sizeof(struct sctp_remote_error)); | ||
404 | 403 | ||
405 | /* Trim the buffer to the right length. */ | 404 | /* Trim the buffer to the right length. */ |
406 | skb_trim(skb, sizeof(struct sctp_remote_error) + elen); | 405 | skb_trim(skb, sizeof(*sre) + elen); |
407 | 406 | ||
408 | /* Socket Extensions for SCTP | 407 | /* RFC6458, Section 6.1.3. SCTP_REMOTE_ERROR */ |
409 | * 5.3.1.3 SCTP_REMOTE_ERROR | 408 | memset(sre, 0, sizeof(*sre)); |
410 | * | ||
411 | * sre_type: | ||
412 | * It should be SCTP_REMOTE_ERROR. | ||
413 | */ | ||
414 | sre->sre_type = SCTP_REMOTE_ERROR; | 409 | sre->sre_type = SCTP_REMOTE_ERROR; |
415 | |||
416 | /* | ||
417 | * Socket Extensions for SCTP | ||
418 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
419 | * | ||
420 | * sre_flags: 16 bits (unsigned integer) | ||
421 | * Currently unused. | ||
422 | */ | ||
423 | sre->sre_flags = 0; | 410 | sre->sre_flags = 0; |
424 | |||
425 | /* Socket Extensions for SCTP | ||
426 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
427 | * | ||
428 | * sre_length: sizeof (__u32) | ||
429 | * | ||
430 | * This field is the total length of the notification data, | ||
431 | * including the notification header. | ||
432 | */ | ||
433 | sre->sre_length = skb->len; | 411 | sre->sre_length = skb->len; |
434 | |||
435 | /* Socket Extensions for SCTP | ||
436 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
437 | * | ||
438 | * sre_error: 16 bits (unsigned integer) | ||
439 | * This value represents one of the Operational Error causes defined in | ||
440 | * the SCTP specification, in network byte order. | ||
441 | */ | ||
442 | sre->sre_error = cause; | 412 | sre->sre_error = cause; |
443 | |||
444 | /* Socket Extensions for SCTP | ||
445 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
446 | * | ||
447 | * sre_assoc_id: sizeof (sctp_assoc_t) | ||
448 | * | ||
449 | * The association id field, holds the identifier for the association. | ||
450 | * All notifications for a given association have the same association | ||
451 | * identifier. For TCP style socket, this field is ignored. | ||
452 | */ | ||
453 | sctp_ulpevent_set_owner(event, asoc); | 413 | sctp_ulpevent_set_owner(event, asoc); |
454 | sre->sre_assoc_id = sctp_assoc2id(asoc); | 414 | sre->sre_assoc_id = sctp_assoc2id(asoc); |
455 | 415 | ||
456 | return event; | 416 | return event; |
457 | |||
458 | fail: | 417 | fail: |
459 | return NULL; | 418 | return NULL; |
460 | } | 419 | } |
@@ -899,7 +858,9 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event) | |||
899 | return notification->sn_header.sn_type; | 858 | return notification->sn_header.sn_type; |
900 | } | 859 | } |
901 | 860 | ||
902 | /* Copy out the sndrcvinfo into a msghdr. */ | 861 | /* RFC6458, Section 5.3.2. SCTP Header Information Structure |
862 | * (SCTP_SNDRCV, DEPRECATED) | ||
863 | */ | ||
903 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | 864 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, |
904 | struct msghdr *msghdr) | 865 | struct msghdr *msghdr) |
905 | { | 866 | { |
@@ -908,74 +869,21 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
908 | if (sctp_ulpevent_is_notification(event)) | 869 | if (sctp_ulpevent_is_notification(event)) |
909 | return; | 870 | return; |
910 | 871 | ||
911 | /* Sockets API Extensions for SCTP | 872 | memset(&sinfo, 0, sizeof(sinfo)); |
912 | * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) | ||
913 | * | ||
914 | * sinfo_stream: 16 bits (unsigned integer) | ||
915 | * | ||
916 | * For recvmsg() the SCTP stack places the message's stream number in | ||
917 | * this value. | ||
918 | */ | ||
919 | sinfo.sinfo_stream = event->stream; | 873 | sinfo.sinfo_stream = event->stream; |
920 | /* sinfo_ssn: 16 bits (unsigned integer) | ||
921 | * | ||
922 | * For recvmsg() this value contains the stream sequence number that | ||
923 | * the remote endpoint placed in the DATA chunk. For fragmented | ||
924 | * messages this is the same number for all deliveries of the message | ||
925 | * (if more than one recvmsg() is needed to read the message). | ||
926 | */ | ||
927 | sinfo.sinfo_ssn = event->ssn; | 874 | sinfo.sinfo_ssn = event->ssn; |
928 | /* sinfo_ppid: 32 bits (unsigned integer) | ||
929 | * | ||
930 | * In recvmsg() this value is | ||
931 | * the same information that was passed by the upper layer in the peer | ||
932 | * application. Please note that byte order issues are NOT accounted | ||
933 | * for and this information is passed opaquely by the SCTP stack from | ||
934 | * one end to the other. | ||
935 | */ | ||
936 | sinfo.sinfo_ppid = event->ppid; | 875 | sinfo.sinfo_ppid = event->ppid; |
937 | /* sinfo_flags: 16 bits (unsigned integer) | ||
938 | * | ||
939 | * This field may contain any of the following flags and is composed of | ||
940 | * a bitwise OR of these values. | ||
941 | * | ||
942 | * recvmsg() flags: | ||
943 | * | ||
944 | * SCTP_UNORDERED - This flag is present when the message was sent | ||
945 | * non-ordered. | ||
946 | */ | ||
947 | sinfo.sinfo_flags = event->flags; | 876 | sinfo.sinfo_flags = event->flags; |
948 | /* sinfo_tsn: 32 bit (unsigned integer) | ||
949 | * | ||
950 | * For the receiving side, this field holds a TSN that was | ||
951 | * assigned to one of the SCTP Data Chunks. | ||
952 | */ | ||
953 | sinfo.sinfo_tsn = event->tsn; | 877 | sinfo.sinfo_tsn = event->tsn; |
954 | /* sinfo_cumtsn: 32 bit (unsigned integer) | ||
955 | * | ||
956 | * This field will hold the current cumulative TSN as | ||
957 | * known by the underlying SCTP layer. Note this field is | ||
958 | * ignored when sending and only valid for a receive | ||
959 | * operation when sinfo_flags are set to SCTP_UNORDERED. | ||
960 | */ | ||
961 | sinfo.sinfo_cumtsn = event->cumtsn; | 878 | sinfo.sinfo_cumtsn = event->cumtsn; |
962 | /* sinfo_assoc_id: sizeof (sctp_assoc_t) | ||
963 | * | ||
964 | * The association handle field, sinfo_assoc_id, holds the identifier | ||
965 | * for the association announced in the COMMUNICATION_UP notification. | ||
966 | * All notifications for a given association have the same identifier. | ||
967 | * Ignored for one-to-one style sockets. | ||
968 | */ | ||
969 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); | 879 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); |
970 | 880 | /* Context value that is set via SCTP_CONTEXT socket option. */ | |
971 | /* context value that is set via SCTP_CONTEXT socket option. */ | ||
972 | sinfo.sinfo_context = event->asoc->default_rcv_context; | 881 | sinfo.sinfo_context = event->asoc->default_rcv_context; |
973 | |||
974 | /* These fields are not used while receiving. */ | 882 | /* These fields are not used while receiving. */ |
975 | sinfo.sinfo_timetolive = 0; | 883 | sinfo.sinfo_timetolive = 0; |
976 | 884 | ||
977 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, | 885 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, |
978 | sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); | 886 | sizeof(sinfo), &sinfo); |
979 | } | 887 | } |
980 | 888 | ||
981 | /* Do accounting for bytes received and hold a reference to the association | 889 | /* Do accounting for bytes received and hold a reference to the association |