diff options
author | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
commit | b10778a00d40b3d9fdaaf5891e802794781ff71c (patch) | |
tree | 6ba4cbac86eecedc3f30650e7f764ecf00c83898 /net/sctp | |
parent | 594081ee7145cc30a3977cb4e218f81213b63dc5 (diff) | |
parent | bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff) |
Merge commit 'v3.17' into next
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/Makefile | 2 | ||||
-rw-r--r-- | net/sctp/associola.c | 12 | ||||
-rw-r--r-- | net/sctp/command.c | 68 | ||||
-rw-r--r-- | net/sctp/input.c | 5 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 156 | ||||
-rw-r--r-- | net/sctp/output.c | 73 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 5 | ||||
-rw-r--r-- | net/sctp/protocol.c | 12 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 4 | ||||
-rw-r--r-- | net/sctp/socket.c | 329 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 5 | ||||
-rw-r--r-- | net/sctp/transport.c | 21 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 65 |
13 files changed, 487 insertions, 270 deletions
diff --git a/net/sctp/Makefile b/net/sctp/Makefile index 5c30b7a873df..3b4ffb021cf1 100644 --- a/net/sctp/Makefile +++ b/net/sctp/Makefile | |||
@@ -8,7 +8,7 @@ obj-$(CONFIG_NET_SCTPPROBE) += sctp_probe.o | |||
8 | sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ | 8 | sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \ |
9 | protocol.o endpointola.o associola.o \ | 9 | protocol.o endpointola.o associola.o \ |
10 | transport.o chunk.o sm_make_chunk.o ulpevent.o \ | 10 | transport.o chunk.o sm_make_chunk.o ulpevent.o \ |
11 | inqueue.o outqueue.o ulpqueue.o command.o \ | 11 | inqueue.o outqueue.o ulpqueue.o \ |
12 | tsnmap.o bind_addr.o socket.o primitive.o \ | 12 | tsnmap.o bind_addr.o socket.o primitive.o \ |
13 | output.o input.o debug.o ssnmap.o auth.o | 13 | output.o input.o debug.o ssnmap.o auth.o |
14 | 14 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 06a9ee6b2d3a..a88b8524846e 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -813,6 +813,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, | |||
813 | else { | 813 | else { |
814 | dst_release(transport->dst); | 814 | dst_release(transport->dst); |
815 | transport->dst = NULL; | 815 | transport->dst = NULL; |
816 | ulp_notify = false; | ||
816 | } | 817 | } |
817 | 818 | ||
818 | spc_state = SCTP_ADDR_UNREACHABLE; | 819 | spc_state = SCTP_ADDR_UNREACHABLE; |
@@ -1244,7 +1245,7 @@ static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr, | |||
1244 | { | 1245 | { |
1245 | u8 score_curr, score_best; | 1246 | u8 score_curr, score_best; |
1246 | 1247 | ||
1247 | if (best == NULL) | 1248 | if (best == NULL || curr == best) |
1248 | return curr; | 1249 | return curr; |
1249 | 1250 | ||
1250 | score_curr = sctp_trans_score(curr); | 1251 | score_curr = sctp_trans_score(curr); |
@@ -1355,14 +1356,11 @@ static void sctp_select_active_and_retran_path(struct sctp_association *asoc) | |||
1355 | trans_sec = trans_pri; | 1356 | trans_sec = trans_pri; |
1356 | 1357 | ||
1357 | /* If we failed to find a usable transport, just camp on the | 1358 | /* If we failed to find a usable transport, just camp on the |
1358 | * primary or retran, even if they are inactive, if possible | 1359 | * active or pick a PF iff it's the better choice. |
1359 | * pick a PF iff it's the better choice. | ||
1360 | */ | 1360 | */ |
1361 | if (trans_pri == NULL) { | 1361 | if (trans_pri == NULL) { |
1362 | trans_pri = sctp_trans_elect_best(asoc->peer.primary_path, | 1362 | trans_pri = sctp_trans_elect_best(asoc->peer.active_path, trans_pf); |
1363 | asoc->peer.retran_path); | 1363 | trans_sec = trans_pri; |
1364 | trans_pri = sctp_trans_elect_best(trans_pri, trans_pf); | ||
1365 | trans_sec = asoc->peer.primary_path; | ||
1366 | } | 1364 | } |
1367 | 1365 | ||
1368 | /* Set the active and retran transports. */ | 1366 | /* Set the active and retran transports. */ |
diff --git a/net/sctp/command.c b/net/sctp/command.c deleted file mode 100644 index dd7375851618..000000000000 --- a/net/sctp/command.c +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | /* SCTP kernel implementation Copyright (C) 1999-2001 | ||
2 | * Cisco, Motorola, and IBM | ||
3 | * Copyright 2001 La Monte H.P. Yarroll | ||
4 | * | ||
5 | * This file is part of the SCTP kernel implementation | ||
6 | * | ||
7 | * These functions manipulate sctp command sequences. | ||
8 | * | ||
9 | * This SCTP implementation is free software; | ||
10 | * you can redistribute it and/or modify it under the terms of | ||
11 | * the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | * This SCTP implementation is distributed in the hope that it | ||
16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | * ************************ | ||
18 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | * See the GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with GNU CC; see the file COPYING. If not, see | ||
23 | * <http://www.gnu.org/licenses/>. | ||
24 | * | ||
25 | * Please send any bug reports or fixes you make to the | ||
26 | * email address(es): | ||
27 | * lksctp developers <linux-sctp@vger.kernel.org> | ||
28 | * | ||
29 | * Written or modified by: | ||
30 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
31 | * Karl Knutson <karl@athena.chicago.il.us> | ||
32 | */ | ||
33 | |||
34 | #include <linux/types.h> | ||
35 | #include <net/sctp/sctp.h> | ||
36 | #include <net/sctp/sm.h> | ||
37 | |||
38 | /* Initialize a block of memory as a command sequence. */ | ||
39 | int sctp_init_cmd_seq(sctp_cmd_seq_t *seq) | ||
40 | { | ||
41 | memset(seq, 0, sizeof(sctp_cmd_seq_t)); | ||
42 | return 1; /* We always succeed. */ | ||
43 | } | ||
44 | |||
45 | /* Add a command to a sctp_cmd_seq_t. | ||
46 | * Return 0 if the command sequence is full. | ||
47 | */ | ||
48 | void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj) | ||
49 | { | ||
50 | BUG_ON(seq->next_free_slot >= SCTP_MAX_NUM_COMMANDS); | ||
51 | |||
52 | seq->cmds[seq->next_free_slot].verb = verb; | ||
53 | seq->cmds[seq->next_free_slot++].obj = obj; | ||
54 | } | ||
55 | |||
56 | /* Return the next command structure in a sctp_cmd_seq. | ||
57 | * Returns NULL at the end of the sequence. | ||
58 | */ | ||
59 | sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq) | ||
60 | { | ||
61 | sctp_cmd_t *retval = NULL; | ||
62 | |||
63 | if (seq->next_cmd < seq->next_free_slot) | ||
64 | retval = &seq->cmds[seq->next_cmd++]; | ||
65 | |||
66 | return retval; | ||
67 | } | ||
68 | |||
diff --git a/net/sctp/input.c b/net/sctp/input.c index f2e2cbd2d750..c1b991294516 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -575,11 +575,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
575 | int err; | 575 | int err; |
576 | struct net *net = dev_net(skb->dev); | 576 | struct net *net = dev_net(skb->dev); |
577 | 577 | ||
578 | if (skb->len < ihlen + 8) { | ||
579 | ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); | ||
580 | return; | ||
581 | } | ||
582 | |||
583 | /* Fix up skb to look at the embedded net header. */ | 578 | /* Fix up skb to look at the embedded net header. */ |
584 | saveip = skb->network_header; | 579 | saveip = skb->network_header; |
585 | savesctp = skb->transport_header; | 580 | savesctp = skb->transport_header; |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 1999592ba88c..0e4198ee2370 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -434,7 +434,7 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk) | |||
434 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ | 434 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ |
435 | static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) | 435 | static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) |
436 | { | 436 | { |
437 | if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { | 437 | if (addr->sa.sa_family == AF_INET) { |
438 | sk->sk_v6_rcv_saddr.s6_addr32[0] = 0; | 438 | sk->sk_v6_rcv_saddr.s6_addr32[0] = 0; |
439 | sk->sk_v6_rcv_saddr.s6_addr32[1] = 0; | 439 | sk->sk_v6_rcv_saddr.s6_addr32[1] = 0; |
440 | sk->sk_v6_rcv_saddr.s6_addr32[2] = htonl(0x0000ffff); | 440 | sk->sk_v6_rcv_saddr.s6_addr32[2] = htonl(0x0000ffff); |
@@ -448,7 +448,7 @@ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) | |||
448 | /* Initialize sk->sk_daddr from sctp_addr. */ | 448 | /* Initialize sk->sk_daddr from sctp_addr. */ |
449 | static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) | 449 | static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) |
450 | { | 450 | { |
451 | if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { | 451 | if (addr->sa.sa_family == AF_INET) { |
452 | sk->sk_v6_daddr.s6_addr32[0] = 0; | 452 | sk->sk_v6_daddr.s6_addr32[0] = 0; |
453 | sk->sk_v6_daddr.s6_addr32[1] = 0; | 453 | sk->sk_v6_daddr.s6_addr32[1] = 0; |
454 | sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); | 454 | sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); |
@@ -556,8 +556,6 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp) | |||
556 | if (IPV6_ADDR_ANY == type) | 556 | if (IPV6_ADDR_ANY == type) |
557 | return 1; | 557 | return 1; |
558 | if (type == IPV6_ADDR_MAPPED) { | 558 | if (type == IPV6_ADDR_MAPPED) { |
559 | if (sp && !sp->v4mapped) | ||
560 | return 0; | ||
561 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) | 559 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) |
562 | return 0; | 560 | return 0; |
563 | sctp_v6_map_v4(addr); | 561 | sctp_v6_map_v4(addr); |
@@ -587,8 +585,6 @@ static int sctp_v6_addr_valid(union sctp_addr *addr, | |||
587 | /* Note: This routine is used in input, so v4-mapped-v6 | 585 | /* Note: This routine is used in input, so v4-mapped-v6 |
588 | * are disallowed here when there is no sctp_sock. | 586 | * are disallowed here when there is no sctp_sock. |
589 | */ | 587 | */ |
590 | if (!sp || !sp->v4mapped) | ||
591 | return 0; | ||
592 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) | 588 | if (sp && ipv6_only_sock(sctp_opt2sk(sp))) |
593 | return 0; | 589 | return 0; |
594 | sctp_v6_map_v4(addr); | 590 | sctp_v6_map_v4(addr); |
@@ -675,11 +671,23 @@ out: | |||
675 | return newsk; | 671 | return newsk; |
676 | } | 672 | } |
677 | 673 | ||
678 | /* Map v4 address to mapped v6 address */ | 674 | /* Format a sockaddr for return to user space. This makes sure the return is |
679 | static void sctp_v6_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr) | 675 | * AF_INET or AF_INET6 depending on the SCTP_I_WANT_MAPPED_V4_ADDR option. |
676 | */ | ||
677 | static int sctp_v6_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) | ||
680 | { | 678 | { |
681 | if (sp->v4mapped && AF_INET == addr->sa.sa_family) | 679 | if (sp->v4mapped) { |
682 | sctp_v4_map_v6(addr); | 680 | if (addr->sa.sa_family == AF_INET) |
681 | sctp_v4_map_v6(addr); | ||
682 | } else { | ||
683 | if (addr->sa.sa_family == AF_INET6 && | ||
684 | ipv6_addr_v4mapped(&addr->v6.sin6_addr)) | ||
685 | sctp_v6_map_v4(addr); | ||
686 | } | ||
687 | |||
688 | if (addr->sa.sa_family == AF_INET) | ||
689 | return sizeof(struct sockaddr_in); | ||
690 | return sizeof(struct sockaddr_in6); | ||
683 | } | 691 | } |
684 | 692 | ||
685 | /* Where did this skb come from? */ | 693 | /* Where did this skb come from? */ |
@@ -706,82 +714,68 @@ static void sctp_v6_ecn_capable(struct sock *sk) | |||
706 | inet6_sk(sk)->tclass |= INET_ECN_ECT_0; | 714 | inet6_sk(sk)->tclass |= INET_ECN_ECT_0; |
707 | } | 715 | } |
708 | 716 | ||
709 | /* Initialize a PF_INET6 socket msg_name. */ | ||
710 | static void sctp_inet6_msgname(char *msgname, int *addr_len) | ||
711 | { | ||
712 | struct sockaddr_in6 *sin6; | ||
713 | |||
714 | sin6 = (struct sockaddr_in6 *)msgname; | ||
715 | sin6->sin6_family = AF_INET6; | ||
716 | sin6->sin6_flowinfo = 0; | ||
717 | sin6->sin6_scope_id = 0; /*FIXME */ | ||
718 | *addr_len = sizeof(struct sockaddr_in6); | ||
719 | } | ||
720 | |||
721 | /* Initialize a PF_INET msgname from a ulpevent. */ | 717 | /* Initialize a PF_INET msgname from a ulpevent. */ |
722 | static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, | 718 | static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, |
723 | char *msgname, int *addrlen) | 719 | char *msgname, int *addrlen) |
724 | { | 720 | { |
725 | struct sockaddr_in6 *sin6, *sin6from; | 721 | union sctp_addr *addr; |
726 | 722 | struct sctp_association *asoc; | |
727 | if (msgname) { | 723 | union sctp_addr *paddr; |
728 | union sctp_addr *addr; | ||
729 | struct sctp_association *asoc; | ||
730 | |||
731 | asoc = event->asoc; | ||
732 | sctp_inet6_msgname(msgname, addrlen); | ||
733 | sin6 = (struct sockaddr_in6 *)msgname; | ||
734 | sin6->sin6_port = htons(asoc->peer.port); | ||
735 | addr = &asoc->peer.primary_addr; | ||
736 | 724 | ||
737 | /* Note: If we go to a common v6 format, this code | 725 | if (!msgname) |
738 | * will change. | 726 | return; |
739 | */ | ||
740 | 727 | ||
741 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | 728 | addr = (union sctp_addr *)msgname; |
742 | if (sctp_sk(asoc->base.sk)->v4mapped && | 729 | asoc = event->asoc; |
743 | AF_INET == addr->sa.sa_family) { | 730 | paddr = &asoc->peer.primary_addr; |
744 | sctp_v4_map_v6((union sctp_addr *)sin6); | ||
745 | sin6->sin6_addr.s6_addr32[3] = | ||
746 | addr->v4.sin_addr.s_addr; | ||
747 | return; | ||
748 | } | ||
749 | 731 | ||
750 | sin6from = &asoc->peer.primary_addr.v6; | 732 | if (paddr->sa.sa_family == AF_INET) { |
751 | sin6->sin6_addr = sin6from->sin6_addr; | 733 | addr->v4.sin_family = AF_INET; |
752 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 734 | addr->v4.sin_port = htons(asoc->peer.port); |
753 | sin6->sin6_scope_id = sin6from->sin6_scope_id; | 735 | addr->v4.sin_addr = paddr->v4.sin_addr; |
736 | } else { | ||
737 | addr->v6.sin6_family = AF_INET6; | ||
738 | addr->v6.sin6_flowinfo = 0; | ||
739 | if (ipv6_addr_type(&paddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) | ||
740 | addr->v6.sin6_scope_id = paddr->v6.sin6_scope_id; | ||
741 | else | ||
742 | addr->v6.sin6_scope_id = 0; | ||
743 | addr->v6.sin6_port = htons(asoc->peer.port); | ||
744 | addr->v6.sin6_addr = paddr->v6.sin6_addr; | ||
754 | } | 745 | } |
746 | |||
747 | *addrlen = sctp_v6_addr_to_user(sctp_sk(asoc->base.sk), addr); | ||
755 | } | 748 | } |
756 | 749 | ||
757 | /* Initialize a msg_name from an inbound skb. */ | 750 | /* Initialize a msg_name from an inbound skb. */ |
758 | static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname, | 751 | static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname, |
759 | int *addr_len) | 752 | int *addr_len) |
760 | { | 753 | { |
754 | union sctp_addr *addr; | ||
761 | struct sctphdr *sh; | 755 | struct sctphdr *sh; |
762 | struct sockaddr_in6 *sin6; | ||
763 | |||
764 | if (msgname) { | ||
765 | sctp_inet6_msgname(msgname, addr_len); | ||
766 | sin6 = (struct sockaddr_in6 *)msgname; | ||
767 | sh = sctp_hdr(skb); | ||
768 | sin6->sin6_port = sh->source; | ||
769 | |||
770 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | ||
771 | if (sctp_sk(skb->sk)->v4mapped && | ||
772 | ip_hdr(skb)->version == 4) { | ||
773 | sctp_v4_map_v6((union sctp_addr *)sin6); | ||
774 | sin6->sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr; | ||
775 | return; | ||
776 | } | ||
777 | 756 | ||
778 | /* Otherwise, just copy the v6 address. */ | 757 | if (!msgname) |
779 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; | 758 | return; |
780 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { | 759 | |
760 | addr = (union sctp_addr *)msgname; | ||
761 | sh = sctp_hdr(skb); | ||
762 | |||
763 | if (ip_hdr(skb)->version == 4) { | ||
764 | addr->v4.sin_family = AF_INET; | ||
765 | addr->v4.sin_port = sh->source; | ||
766 | addr->v4.sin_addr.s_addr = ip_hdr(skb)->saddr; | ||
767 | } else { | ||
768 | addr->v6.sin6_family = AF_INET6; | ||
769 | addr->v6.sin6_flowinfo = 0; | ||
770 | addr->v6.sin6_port = sh->source; | ||
771 | addr->v6.sin6_addr = ipv6_hdr(skb)->saddr; | ||
772 | if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { | ||
781 | struct sctp_ulpevent *ev = sctp_skb2event(skb); | 773 | struct sctp_ulpevent *ev = sctp_skb2event(skb); |
782 | sin6->sin6_scope_id = ev->iif; | 774 | addr->v6.sin6_scope_id = ev->iif; |
783 | } | 775 | } |
784 | } | 776 | } |
777 | |||
778 | *addr_len = sctp_v6_addr_to_user(sctp_sk(skb->sk), addr); | ||
785 | } | 779 | } |
786 | 780 | ||
787 | /* Do we support this AF? */ | 781 | /* Do we support this AF? */ |
@@ -857,9 +851,6 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) | |||
857 | return 0; | 851 | return 0; |
858 | } | 852 | } |
859 | rcu_read_unlock(); | 853 | rcu_read_unlock(); |
860 | } else if (type == IPV6_ADDR_MAPPED) { | ||
861 | if (!opt->v4mapped) | ||
862 | return 0; | ||
863 | } | 854 | } |
864 | 855 | ||
865 | af = opt->pf->af; | 856 | af = opt->pf->af; |
@@ -914,6 +905,23 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt, | |||
914 | return 1; | 905 | return 1; |
915 | } | 906 | } |
916 | 907 | ||
908 | /* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */ | ||
909 | static int sctp_getname(struct socket *sock, struct sockaddr *uaddr, | ||
910 | int *uaddr_len, int peer) | ||
911 | { | ||
912 | int rc; | ||
913 | |||
914 | rc = inet6_getname(sock, uaddr, uaddr_len, peer); | ||
915 | |||
916 | if (rc != 0) | ||
917 | return rc; | ||
918 | |||
919 | *uaddr_len = sctp_v6_addr_to_user(sctp_sk(sock->sk), | ||
920 | (union sctp_addr *)uaddr); | ||
921 | |||
922 | return rc; | ||
923 | } | ||
924 | |||
917 | static const struct proto_ops inet6_seqpacket_ops = { | 925 | static const struct proto_ops inet6_seqpacket_ops = { |
918 | .family = PF_INET6, | 926 | .family = PF_INET6, |
919 | .owner = THIS_MODULE, | 927 | .owner = THIS_MODULE, |
@@ -922,7 +930,7 @@ static const struct proto_ops inet6_seqpacket_ops = { | |||
922 | .connect = inet_dgram_connect, | 930 | .connect = inet_dgram_connect, |
923 | .socketpair = sock_no_socketpair, | 931 | .socketpair = sock_no_socketpair, |
924 | .accept = inet_accept, | 932 | .accept = inet_accept, |
925 | .getname = inet6_getname, | 933 | .getname = sctp_getname, |
926 | .poll = sctp_poll, | 934 | .poll = sctp_poll, |
927 | .ioctl = inet6_ioctl, | 935 | .ioctl = inet6_ioctl, |
928 | .listen = sctp_inet_listen, | 936 | .listen = sctp_inet_listen, |
@@ -974,8 +982,6 @@ static struct sctp_af sctp_af_inet6 = { | |||
974 | .copy_addrlist = sctp_v6_copy_addrlist, | 982 | .copy_addrlist = sctp_v6_copy_addrlist, |
975 | .from_skb = sctp_v6_from_skb, | 983 | .from_skb = sctp_v6_from_skb, |
976 | .from_sk = sctp_v6_from_sk, | 984 | .from_sk = sctp_v6_from_sk, |
977 | .to_sk_saddr = sctp_v6_to_sk_saddr, | ||
978 | .to_sk_daddr = sctp_v6_to_sk_daddr, | ||
979 | .from_addr_param = sctp_v6_from_addr_param, | 985 | .from_addr_param = sctp_v6_from_addr_param, |
980 | .to_addr_param = sctp_v6_to_addr_param, | 986 | .to_addr_param = sctp_v6_to_addr_param, |
981 | .cmp_addr = sctp_v6_cmp_addr, | 987 | .cmp_addr = sctp_v6_cmp_addr, |
@@ -1005,7 +1011,9 @@ static struct sctp_pf sctp_pf_inet6 = { | |||
1005 | .send_verify = sctp_inet6_send_verify, | 1011 | .send_verify = sctp_inet6_send_verify, |
1006 | .supported_addrs = sctp_inet6_supported_addrs, | 1012 | .supported_addrs = sctp_inet6_supported_addrs, |
1007 | .create_accept_sk = sctp_v6_create_accept_sk, | 1013 | .create_accept_sk = sctp_v6_create_accept_sk, |
1008 | .addr_v4map = sctp_v6_addr_v4map, | 1014 | .addr_to_user = sctp_v6_addr_to_user, |
1015 | .to_sk_saddr = sctp_v6_to_sk_saddr, | ||
1016 | .to_sk_daddr = sctp_v6_to_sk_daddr, | ||
1009 | .af = &sctp_af_inet6, | 1017 | .af = &sctp_af_inet6, |
1010 | }; | 1018 | }; |
1011 | 1019 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index 01ab8e0723f0..42dffd428389 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -178,7 +178,7 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, | |||
178 | 178 | ||
179 | case SCTP_XMIT_RWND_FULL: | 179 | case SCTP_XMIT_RWND_FULL: |
180 | case SCTP_XMIT_OK: | 180 | case SCTP_XMIT_OK: |
181 | case SCTP_XMIT_NAGLE_DELAY: | 181 | case SCTP_XMIT_DELAY: |
182 | break; | 182 | break; |
183 | } | 183 | } |
184 | 184 | ||
@@ -599,7 +599,7 @@ out: | |||
599 | return err; | 599 | return err; |
600 | no_route: | 600 | no_route: |
601 | kfree_skb(nskb); | 601 | kfree_skb(nskb); |
602 | IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); | 602 | IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); |
603 | 603 | ||
604 | /* FIXME: Returning the 'err' will effect all the associations | 604 | /* FIXME: Returning the 'err' will effect all the associations |
605 | * associated with a socket, although only one of the paths of the | 605 | * associated with a socket, although only one of the paths of the |
@@ -633,7 +633,6 @@ nomem: | |||
633 | static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | 633 | static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, |
634 | struct sctp_chunk *chunk) | 634 | struct sctp_chunk *chunk) |
635 | { | 635 | { |
636 | sctp_xmit_t retval = SCTP_XMIT_OK; | ||
637 | size_t datasize, rwnd, inflight, flight_size; | 636 | size_t datasize, rwnd, inflight, flight_size; |
638 | struct sctp_transport *transport = packet->transport; | 637 | struct sctp_transport *transport = packet->transport; |
639 | struct sctp_association *asoc = transport->asoc; | 638 | struct sctp_association *asoc = transport->asoc; |
@@ -658,15 +657,11 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | |||
658 | 657 | ||
659 | datasize = sctp_data_size(chunk); | 658 | datasize = sctp_data_size(chunk); |
660 | 659 | ||
661 | if (datasize > rwnd) { | 660 | if (datasize > rwnd && inflight > 0) |
662 | if (inflight > 0) { | 661 | /* We have (at least) one data chunk in flight, |
663 | /* We have (at least) one data chunk in flight, | 662 | * so we can't fall back to rule 6.1 B). |
664 | * so we can't fall back to rule 6.1 B). | 663 | */ |
665 | */ | 664 | return SCTP_XMIT_RWND_FULL; |
666 | retval = SCTP_XMIT_RWND_FULL; | ||
667 | goto finish; | ||
668 | } | ||
669 | } | ||
670 | 665 | ||
671 | /* RFC 2960 6.1 Transmission of DATA Chunks | 666 | /* RFC 2960 6.1 Transmission of DATA Chunks |
672 | * | 667 | * |
@@ -680,36 +675,44 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | |||
680 | * When a Fast Retransmit is being performed the sender SHOULD | 675 | * When a Fast Retransmit is being performed the sender SHOULD |
681 | * ignore the value of cwnd and SHOULD NOT delay retransmission. | 676 | * ignore the value of cwnd and SHOULD NOT delay retransmission. |
682 | */ | 677 | */ |
683 | if (chunk->fast_retransmit != SCTP_NEED_FRTX) | 678 | if (chunk->fast_retransmit != SCTP_NEED_FRTX && |
684 | if (flight_size >= transport->cwnd) { | 679 | flight_size >= transport->cwnd) |
685 | retval = SCTP_XMIT_RWND_FULL; | 680 | return SCTP_XMIT_RWND_FULL; |
686 | goto finish; | ||
687 | } | ||
688 | 681 | ||
689 | /* Nagle's algorithm to solve small-packet problem: | 682 | /* Nagle's algorithm to solve small-packet problem: |
690 | * Inhibit the sending of new chunks when new outgoing data arrives | 683 | * Inhibit the sending of new chunks when new outgoing data arrives |
691 | * if any previously transmitted data on the connection remains | 684 | * if any previously transmitted data on the connection remains |
692 | * unacknowledged. | 685 | * unacknowledged. |
693 | */ | 686 | */ |
694 | if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) && | ||
695 | inflight && sctp_state(asoc, ESTABLISHED)) { | ||
696 | unsigned int max = transport->pathmtu - packet->overhead; | ||
697 | unsigned int len = chunk->skb->len + q->out_qlen; | ||
698 | |||
699 | /* Check whether this chunk and all the rest of pending | ||
700 | * data will fit or delay in hopes of bundling a full | ||
701 | * sized packet. | ||
702 | * Don't delay large message writes that may have been | ||
703 | * fragmeneted into small peices. | ||
704 | */ | ||
705 | if ((len < max) && chunk->msg->can_delay) { | ||
706 | retval = SCTP_XMIT_NAGLE_DELAY; | ||
707 | goto finish; | ||
708 | } | ||
709 | } | ||
710 | 687 | ||
711 | finish: | 688 | if (sctp_sk(asoc->base.sk)->nodelay) |
712 | return retval; | 689 | /* Nagle disabled */ |
690 | return SCTP_XMIT_OK; | ||
691 | |||
692 | if (!sctp_packet_empty(packet)) | ||
693 | /* Append to packet */ | ||
694 | return SCTP_XMIT_OK; | ||
695 | |||
696 | if (inflight == 0) | ||
697 | /* Nothing unacked */ | ||
698 | return SCTP_XMIT_OK; | ||
699 | |||
700 | if (!sctp_state(asoc, ESTABLISHED)) | ||
701 | return SCTP_XMIT_OK; | ||
702 | |||
703 | /* Check whether this chunk and all the rest of pending data will fit | ||
704 | * or delay in hopes of bundling a full sized packet. | ||
705 | */ | ||
706 | if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead) | ||
707 | /* Enough data queued to fill a packet */ | ||
708 | return SCTP_XMIT_OK; | ||
709 | |||
710 | /* Don't delay large message writes that may have been fragmented */ | ||
711 | if (!chunk->msg->can_delay) | ||
712 | return SCTP_XMIT_OK; | ||
713 | |||
714 | /* Defer until all data acked or packet full */ | ||
715 | return SCTP_XMIT_DELAY; | ||
713 | } | 716 | } |
714 | 717 | ||
715 | /* This private function does management things when adding DATA chunk */ | 718 | /* This private function does management things when adding DATA chunk */ |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 9c77947c0597..7e8f0a117106 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -629,7 +629,7 @@ redo: | |||
629 | done = 1; | 629 | done = 1; |
630 | break; | 630 | break; |
631 | 631 | ||
632 | case SCTP_XMIT_NAGLE_DELAY: | 632 | case SCTP_XMIT_DELAY: |
633 | /* Send this packet. */ | 633 | /* Send this packet. */ |
634 | error = sctp_packet_transmit(pkt); | 634 | error = sctp_packet_transmit(pkt); |
635 | 635 | ||
@@ -1015,7 +1015,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1015 | switch (status) { | 1015 | switch (status) { |
1016 | case SCTP_XMIT_PMTU_FULL: | 1016 | case SCTP_XMIT_PMTU_FULL: |
1017 | case SCTP_XMIT_RWND_FULL: | 1017 | case SCTP_XMIT_RWND_FULL: |
1018 | case SCTP_XMIT_NAGLE_DELAY: | 1018 | case SCTP_XMIT_DELAY: |
1019 | /* We could not append this chunk, so put | 1019 | /* We could not append this chunk, so put |
1020 | * the chunk back on the output queue. | 1020 | * the chunk back on the output queue. |
1021 | */ | 1021 | */ |
@@ -1025,7 +1025,6 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1025 | 1025 | ||
1026 | sctp_outq_head_data(q, chunk); | 1026 | sctp_outq_head_data(q, chunk); |
1027 | goto sctp_flush_out; | 1027 | goto sctp_flush_out; |
1028 | break; | ||
1029 | 1028 | ||
1030 | case SCTP_XMIT_OK: | 1029 | case SCTP_XMIT_OK: |
1031 | /* The sender is in the SHUTDOWN-PENDING state, | 1030 | /* The sender is in the SHUTDOWN-PENDING state, |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 6789d785e698..6240834f4b95 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -576,10 +576,10 @@ out: | |||
576 | return newsk; | 576 | return newsk; |
577 | } | 577 | } |
578 | 578 | ||
579 | /* Map address, empty for v4 family */ | 579 | static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) |
580 | static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr) | ||
581 | { | 580 | { |
582 | /* Empty */ | 581 | /* No address mapping for V4 sockets */ |
582 | return sizeof(struct sockaddr_in); | ||
583 | } | 583 | } |
584 | 584 | ||
585 | /* Dump the v4 addr to the seq file. */ | 585 | /* Dump the v4 addr to the seq file. */ |
@@ -976,7 +976,9 @@ static struct sctp_pf sctp_pf_inet = { | |||
976 | .send_verify = sctp_inet_send_verify, | 976 | .send_verify = sctp_inet_send_verify, |
977 | .supported_addrs = sctp_inet_supported_addrs, | 977 | .supported_addrs = sctp_inet_supported_addrs, |
978 | .create_accept_sk = sctp_v4_create_accept_sk, | 978 | .create_accept_sk = sctp_v4_create_accept_sk, |
979 | .addr_v4map = sctp_v4_addr_v4map, | 979 | .addr_to_user = sctp_v4_addr_to_user, |
980 | .to_sk_saddr = sctp_v4_to_sk_saddr, | ||
981 | .to_sk_daddr = sctp_v4_to_sk_daddr, | ||
980 | .af = &sctp_af_inet | 982 | .af = &sctp_af_inet |
981 | }; | 983 | }; |
982 | 984 | ||
@@ -1047,8 +1049,6 @@ static struct sctp_af sctp_af_inet = { | |||
1047 | .copy_addrlist = sctp_v4_copy_addrlist, | 1049 | .copy_addrlist = sctp_v4_copy_addrlist, |
1048 | .from_skb = sctp_v4_from_skb, | 1050 | .from_skb = sctp_v4_from_skb, |
1049 | .from_sk = sctp_v4_from_sk, | 1051 | .from_sk = sctp_v4_from_sk, |
1050 | .to_sk_saddr = sctp_v4_to_sk_saddr, | ||
1051 | .to_sk_daddr = sctp_v4_to_sk_daddr, | ||
1052 | .from_addr_param = sctp_v4_from_addr_param, | 1052 | .from_addr_param = sctp_v4_from_addr_param, |
1053 | .to_addr_param = sctp_v4_to_addr_param, | 1053 | .to_addr_param = sctp_v4_to_addr_param, |
1054 | .cmp_addr = sctp_v4_cmp_addr, | 1054 | .cmp_addr = sctp_v4_cmp_addr, |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5170a1ff95a1..d3f1ea460c50 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -4182,7 +4182,6 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net, | |||
4182 | case SCTP_CID_ACTION_DISCARD: | 4182 | case SCTP_CID_ACTION_DISCARD: |
4183 | /* Discard the packet. */ | 4183 | /* Discard the packet. */ |
4184 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | 4184 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); |
4185 | break; | ||
4186 | case SCTP_CID_ACTION_DISCARD_ERR: | 4185 | case SCTP_CID_ACTION_DISCARD_ERR: |
4187 | /* Generate an ERROR chunk as response. */ | 4186 | /* Generate an ERROR chunk as response. */ |
4188 | hdr = unk_chunk->chunk_hdr; | 4187 | hdr = unk_chunk->chunk_hdr; |
@@ -4198,11 +4197,9 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net, | |||
4198 | /* Discard the packet. */ | 4197 | /* Discard the packet. */ |
4199 | sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | 4198 | sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); |
4200 | return SCTP_DISPOSITION_CONSUME; | 4199 | return SCTP_DISPOSITION_CONSUME; |
4201 | break; | ||
4202 | case SCTP_CID_ACTION_SKIP: | 4200 | case SCTP_CID_ACTION_SKIP: |
4203 | /* Skip the chunk. */ | 4201 | /* Skip the chunk. */ |
4204 | return SCTP_DISPOSITION_DISCARD; | 4202 | return SCTP_DISPOSITION_DISCARD; |
4205 | break; | ||
4206 | case SCTP_CID_ACTION_SKIP_ERR: | 4203 | case SCTP_CID_ACTION_SKIP_ERR: |
4207 | /* Generate an ERROR chunk as response. */ | 4204 | /* Generate an ERROR chunk as response. */ |
4208 | hdr = unk_chunk->chunk_hdr; | 4205 | hdr = unk_chunk->chunk_hdr; |
@@ -4216,7 +4213,6 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net, | |||
4216 | } | 4213 | } |
4217 | /* Skip the chunk. */ | 4214 | /* Skip the chunk. */ |
4218 | return SCTP_DISPOSITION_CONSUME; | 4215 | return SCTP_DISPOSITION_CONSUME; |
4219 | break; | ||
4220 | default: | 4216 | default: |
4221 | break; | 4217 | break; |
4222 | } | 4218 | } |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 429899689408..634a2abb5f3a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -254,7 +254,7 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk, | |||
254 | if (id_asoc && (id_asoc != addr_asoc)) | 254 | if (id_asoc && (id_asoc != addr_asoc)) |
255 | return NULL; | 255 | return NULL; |
256 | 256 | ||
257 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 257 | sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk), |
258 | (union sctp_addr *)addr); | 258 | (union sctp_addr *)addr); |
259 | 259 | ||
260 | return transport; | 260 | return transport; |
@@ -396,7 +396,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
396 | /* Copy back into socket for getsockname() use. */ | 396 | /* Copy back into socket for getsockname() use. */ |
397 | if (!ret) { | 397 | if (!ret) { |
398 | inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num); | 398 | inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num); |
399 | af->to_sk_saddr(addr, sk); | 399 | sp->pf->to_sk_saddr(addr, sk); |
400 | } | 400 | } |
401 | 401 | ||
402 | return ret; | 402 | return ret; |
@@ -1053,7 +1053,6 @@ static int __sctp_connect(struct sock *sk, | |||
1053 | struct sctp_association *asoc2; | 1053 | struct sctp_association *asoc2; |
1054 | struct sctp_transport *transport; | 1054 | struct sctp_transport *transport; |
1055 | union sctp_addr to; | 1055 | union sctp_addr to; |
1056 | struct sctp_af *af; | ||
1057 | sctp_scope_t scope; | 1056 | sctp_scope_t scope; |
1058 | long timeo; | 1057 | long timeo; |
1059 | int err = 0; | 1058 | int err = 0; |
@@ -1081,6 +1080,8 @@ static int __sctp_connect(struct sock *sk, | |||
1081 | /* Walk through the addrs buffer and count the number of addresses. */ | 1080 | /* Walk through the addrs buffer and count the number of addresses. */ |
1082 | addr_buf = kaddrs; | 1081 | addr_buf = kaddrs; |
1083 | while (walk_size < addrs_size) { | 1082 | while (walk_size < addrs_size) { |
1083 | struct sctp_af *af; | ||
1084 | |||
1084 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | 1085 | if (walk_size + sizeof(sa_family_t) > addrs_size) { |
1085 | err = -EINVAL; | 1086 | err = -EINVAL; |
1086 | goto out_free; | 1087 | goto out_free; |
@@ -1205,8 +1206,7 @@ static int __sctp_connect(struct sock *sk, | |||
1205 | 1206 | ||
1206 | /* Initialize sk's dport and daddr for getpeername() */ | 1207 | /* Initialize sk's dport and daddr for getpeername() */ |
1207 | inet_sk(sk)->inet_dport = htons(asoc->peer.port); | 1208 | inet_sk(sk)->inet_dport = htons(asoc->peer.port); |
1208 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | 1209 | sp->pf->to_sk_daddr(sa_addr, sk); |
1209 | af->to_sk_daddr(sa_addr, sk); | ||
1210 | sk->sk_err = 0; | 1210 | sk->sk_err = 0; |
1211 | 1211 | ||
1212 | /* in-kernel sockets don't generally have a file allocated to them | 1212 | /* in-kernel sockets don't generally have a file allocated to them |
@@ -1602,12 +1602,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1602 | struct sctp_initmsg *sinit; | 1602 | struct sctp_initmsg *sinit; |
1603 | sctp_assoc_t associd = 0; | 1603 | sctp_assoc_t associd = 0; |
1604 | sctp_cmsgs_t cmsgs = { NULL }; | 1604 | sctp_cmsgs_t cmsgs = { NULL }; |
1605 | int err; | ||
1606 | sctp_scope_t scope; | 1605 | sctp_scope_t scope; |
1607 | long timeo; | 1606 | bool fill_sinfo_ttl = false; |
1608 | __u16 sinfo_flags = 0; | ||
1609 | struct sctp_datamsg *datamsg; | 1607 | struct sctp_datamsg *datamsg; |
1610 | int msg_flags = msg->msg_flags; | 1608 | int msg_flags = msg->msg_flags; |
1609 | __u16 sinfo_flags = 0; | ||
1610 | long timeo; | ||
1611 | int err; | ||
1611 | 1612 | ||
1612 | err = 0; | 1613 | err = 0; |
1613 | sp = sctp_sk(sk); | 1614 | sp = sctp_sk(sk); |
@@ -1648,10 +1649,21 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1648 | msg_name = msg->msg_name; | 1649 | msg_name = msg->msg_name; |
1649 | } | 1650 | } |
1650 | 1651 | ||
1651 | sinfo = cmsgs.info; | ||
1652 | sinit = cmsgs.init; | 1652 | sinit = cmsgs.init; |
1653 | if (cmsgs.sinfo != NULL) { | ||
1654 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | ||
1655 | default_sinfo.sinfo_stream = cmsgs.sinfo->snd_sid; | ||
1656 | default_sinfo.sinfo_flags = cmsgs.sinfo->snd_flags; | ||
1657 | default_sinfo.sinfo_ppid = cmsgs.sinfo->snd_ppid; | ||
1658 | default_sinfo.sinfo_context = cmsgs.sinfo->snd_context; | ||
1659 | default_sinfo.sinfo_assoc_id = cmsgs.sinfo->snd_assoc_id; | ||
1653 | 1660 | ||
1654 | /* Did the user specify SNDRCVINFO? */ | 1661 | sinfo = &default_sinfo; |
1662 | fill_sinfo_ttl = true; | ||
1663 | } else { | ||
1664 | sinfo = cmsgs.srinfo; | ||
1665 | } | ||
1666 | /* Did the user specify SNDINFO/SNDRCVINFO? */ | ||
1655 | if (sinfo) { | 1667 | if (sinfo) { |
1656 | sinfo_flags = sinfo->sinfo_flags; | 1668 | sinfo_flags = sinfo->sinfo_flags; |
1657 | associd = sinfo->sinfo_assoc_id; | 1669 | associd = sinfo->sinfo_assoc_id; |
@@ -1858,8 +1870,8 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1858 | pr_debug("%s: we have a valid association\n", __func__); | 1870 | pr_debug("%s: we have a valid association\n", __func__); |
1859 | 1871 | ||
1860 | if (!sinfo) { | 1872 | if (!sinfo) { |
1861 | /* If the user didn't specify SNDRCVINFO, make up one with | 1873 | /* If the user didn't specify SNDINFO/SNDRCVINFO, make up |
1862 | * some defaults. | 1874 | * one with some defaults. |
1863 | */ | 1875 | */ |
1864 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | 1876 | memset(&default_sinfo, 0, sizeof(default_sinfo)); |
1865 | default_sinfo.sinfo_stream = asoc->default_stream; | 1877 | default_sinfo.sinfo_stream = asoc->default_stream; |
@@ -1868,7 +1880,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1868 | default_sinfo.sinfo_context = asoc->default_context; | 1880 | default_sinfo.sinfo_context = asoc->default_context; |
1869 | default_sinfo.sinfo_timetolive = asoc->default_timetolive; | 1881 | default_sinfo.sinfo_timetolive = asoc->default_timetolive; |
1870 | default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); | 1882 | default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); |
1883 | |||
1871 | sinfo = &default_sinfo; | 1884 | sinfo = &default_sinfo; |
1885 | } else if (fill_sinfo_ttl) { | ||
1886 | /* In case SNDINFO was specified, we still need to fill | ||
1887 | * it with a default ttl from the assoc here. | ||
1888 | */ | ||
1889 | sinfo->sinfo_timetolive = asoc->default_timetolive; | ||
1872 | } | 1890 | } |
1873 | 1891 | ||
1874 | /* API 7.1.7, the sndbuf size per association bounds the | 1892 | /* API 7.1.7, the sndbuf size per association bounds the |
@@ -2042,8 +2060,6 @@ static int sctp_skb_pull(struct sk_buff *skb, int len) | |||
2042 | * flags - flags sent or received with the user message, see Section | 2060 | * flags - flags sent or received with the user message, see Section |
2043 | * 5 for complete description of the flags. | 2061 | * 5 for complete description of the flags. |
2044 | */ | 2062 | */ |
2045 | static struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *); | ||
2046 | |||
2047 | static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | 2063 | static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, |
2048 | struct msghdr *msg, size_t len, int noblock, | 2064 | struct msghdr *msg, size_t len, int noblock, |
2049 | int flags, int *addr_len) | 2065 | int flags, int *addr_len) |
@@ -2094,9 +2110,16 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
2094 | sp->pf->skb_msgname(skb, msg->msg_name, addr_len); | 2110 | sp->pf->skb_msgname(skb, msg->msg_name, addr_len); |
2095 | } | 2111 | } |
2096 | 2112 | ||
2113 | /* Check if we allow SCTP_NXTINFO. */ | ||
2114 | if (sp->recvnxtinfo) | ||
2115 | sctp_ulpevent_read_nxtinfo(event, msg, sk); | ||
2116 | /* Check if we allow SCTP_RCVINFO. */ | ||
2117 | if (sp->recvrcvinfo) | ||
2118 | sctp_ulpevent_read_rcvinfo(event, msg); | ||
2097 | /* Check if we allow SCTP_SNDRCVINFO. */ | 2119 | /* Check if we allow SCTP_SNDRCVINFO. */ |
2098 | if (sp->subscribe.sctp_data_io_event) | 2120 | if (sp->subscribe.sctp_data_io_event) |
2099 | sctp_ulpevent_read_sndrcvinfo(event, msg); | 2121 | sctp_ulpevent_read_sndrcvinfo(event, msg); |
2122 | |||
2100 | #if 0 | 2123 | #if 0 |
2101 | /* FIXME: we should be calling IP/IPv6 layers. */ | 2124 | /* FIXME: we should be calling IP/IPv6 layers. */ |
2102 | if (sk->sk_protinfo.af_inet.cmsg_flags) | 2125 | if (sk->sk_protinfo.af_inet.cmsg_flags) |
@@ -2182,8 +2205,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2182 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | 2205 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) |
2183 | return -EFAULT; | 2206 | return -EFAULT; |
2184 | 2207 | ||
2185 | /* | 2208 | if (sctp_sk(sk)->subscribe.sctp_data_io_event) |
2186 | * At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | 2209 | pr_warn_ratelimited(DEPRECATED "%s (pid %d) " |
2210 | "Requested SCTP_SNDRCVINFO event.\n" | ||
2211 | "Use SCTP_RCVINFO through SCTP_RECVRCVINFO option instead.\n", | ||
2212 | current->comm, task_pid_nr(current)); | ||
2213 | |||
2214 | /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | ||
2187 | * if there is no data to be sent or retransmit, the stack will | 2215 | * if there is no data to be sent or retransmit, the stack will |
2188 | * immediately send up this notification. | 2216 | * immediately send up this notification. |
2189 | */ | 2217 | */ |
@@ -2747,19 +2775,22 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2747 | char __user *optval, | 2775 | char __user *optval, |
2748 | unsigned int optlen) | 2776 | unsigned int optlen) |
2749 | { | 2777 | { |
2750 | struct sctp_sndrcvinfo info; | ||
2751 | struct sctp_association *asoc; | ||
2752 | struct sctp_sock *sp = sctp_sk(sk); | 2778 | struct sctp_sock *sp = sctp_sk(sk); |
2779 | struct sctp_association *asoc; | ||
2780 | struct sctp_sndrcvinfo info; | ||
2753 | 2781 | ||
2754 | if (optlen != sizeof(struct sctp_sndrcvinfo)) | 2782 | if (optlen != sizeof(info)) |
2755 | return -EINVAL; | 2783 | return -EINVAL; |
2756 | if (copy_from_user(&info, optval, optlen)) | 2784 | if (copy_from_user(&info, optval, optlen)) |
2757 | return -EFAULT; | 2785 | return -EFAULT; |
2786 | if (info.sinfo_flags & | ||
2787 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
2788 | SCTP_ABORT | SCTP_EOF)) | ||
2789 | return -EINVAL; | ||
2758 | 2790 | ||
2759 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | 2791 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); |
2760 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) | 2792 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) |
2761 | return -EINVAL; | 2793 | return -EINVAL; |
2762 | |||
2763 | if (asoc) { | 2794 | if (asoc) { |
2764 | asoc->default_stream = info.sinfo_stream; | 2795 | asoc->default_stream = info.sinfo_stream; |
2765 | asoc->default_flags = info.sinfo_flags; | 2796 | asoc->default_flags = info.sinfo_flags; |
@@ -2777,6 +2808,44 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2777 | return 0; | 2808 | return 0; |
2778 | } | 2809 | } |
2779 | 2810 | ||
2811 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | ||
2812 | * (SCTP_DEFAULT_SNDINFO) | ||
2813 | */ | ||
2814 | static int sctp_setsockopt_default_sndinfo(struct sock *sk, | ||
2815 | char __user *optval, | ||
2816 | unsigned int optlen) | ||
2817 | { | ||
2818 | struct sctp_sock *sp = sctp_sk(sk); | ||
2819 | struct sctp_association *asoc; | ||
2820 | struct sctp_sndinfo info; | ||
2821 | |||
2822 | if (optlen != sizeof(info)) | ||
2823 | return -EINVAL; | ||
2824 | if (copy_from_user(&info, optval, optlen)) | ||
2825 | return -EFAULT; | ||
2826 | if (info.snd_flags & | ||
2827 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
2828 | SCTP_ABORT | SCTP_EOF)) | ||
2829 | return -EINVAL; | ||
2830 | |||
2831 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | ||
2832 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)) | ||
2833 | return -EINVAL; | ||
2834 | if (asoc) { | ||
2835 | asoc->default_stream = info.snd_sid; | ||
2836 | asoc->default_flags = info.snd_flags; | ||
2837 | asoc->default_ppid = info.snd_ppid; | ||
2838 | asoc->default_context = info.snd_context; | ||
2839 | } else { | ||
2840 | sp->default_stream = info.snd_sid; | ||
2841 | sp->default_flags = info.snd_flags; | ||
2842 | sp->default_ppid = info.snd_ppid; | ||
2843 | sp->default_context = info.snd_context; | ||
2844 | } | ||
2845 | |||
2846 | return 0; | ||
2847 | } | ||
2848 | |||
2780 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) | 2849 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) |
2781 | * | 2850 | * |
2782 | * Requests that the local SCTP stack use the enclosed peer address as | 2851 | * Requests that the local SCTP stack use the enclosed peer address as |
@@ -3523,7 +3592,6 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, | |||
3523 | return 0; | 3592 | return 0; |
3524 | } | 3593 | } |
3525 | 3594 | ||
3526 | |||
3527 | /* | 3595 | /* |
3528 | * SCTP_PEER_ADDR_THLDS | 3596 | * SCTP_PEER_ADDR_THLDS |
3529 | * | 3597 | * |
@@ -3574,6 +3642,38 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk, | |||
3574 | return 0; | 3642 | return 0; |
3575 | } | 3643 | } |
3576 | 3644 | ||
3645 | static int sctp_setsockopt_recvrcvinfo(struct sock *sk, | ||
3646 | char __user *optval, | ||
3647 | unsigned int optlen) | ||
3648 | { | ||
3649 | int val; | ||
3650 | |||
3651 | if (optlen < sizeof(int)) | ||
3652 | return -EINVAL; | ||
3653 | if (get_user(val, (int __user *) optval)) | ||
3654 | return -EFAULT; | ||
3655 | |||
3656 | sctp_sk(sk)->recvrcvinfo = (val == 0) ? 0 : 1; | ||
3657 | |||
3658 | return 0; | ||
3659 | } | ||
3660 | |||
3661 | static int sctp_setsockopt_recvnxtinfo(struct sock *sk, | ||
3662 | char __user *optval, | ||
3663 | unsigned int optlen) | ||
3664 | { | ||
3665 | int val; | ||
3666 | |||
3667 | if (optlen < sizeof(int)) | ||
3668 | return -EINVAL; | ||
3669 | if (get_user(val, (int __user *) optval)) | ||
3670 | return -EFAULT; | ||
3671 | |||
3672 | sctp_sk(sk)->recvnxtinfo = (val == 0) ? 0 : 1; | ||
3673 | |||
3674 | return 0; | ||
3675 | } | ||
3676 | |||
3577 | /* API 6.2 setsockopt(), getsockopt() | 3677 | /* API 6.2 setsockopt(), getsockopt() |
3578 | * | 3678 | * |
3579 | * Applications use setsockopt() and getsockopt() to set or retrieve | 3679 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -3671,6 +3771,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3671 | retval = sctp_setsockopt_default_send_param(sk, optval, | 3771 | retval = sctp_setsockopt_default_send_param(sk, optval, |
3672 | optlen); | 3772 | optlen); |
3673 | break; | 3773 | break; |
3774 | case SCTP_DEFAULT_SNDINFO: | ||
3775 | retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen); | ||
3776 | break; | ||
3674 | case SCTP_PRIMARY_ADDR: | 3777 | case SCTP_PRIMARY_ADDR: |
3675 | retval = sctp_setsockopt_primary_addr(sk, optval, optlen); | 3778 | retval = sctp_setsockopt_primary_addr(sk, optval, optlen); |
3676 | break; | 3779 | break; |
@@ -3725,6 +3828,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3725 | case SCTP_PEER_ADDR_THLDS: | 3828 | case SCTP_PEER_ADDR_THLDS: |
3726 | retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); | 3829 | retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); |
3727 | break; | 3830 | break; |
3831 | case SCTP_RECVRCVINFO: | ||
3832 | retval = sctp_setsockopt_recvrcvinfo(sk, optval, optlen); | ||
3833 | break; | ||
3834 | case SCTP_RECVNXTINFO: | ||
3835 | retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen); | ||
3836 | break; | ||
3728 | default: | 3837 | default: |
3729 | retval = -ENOPROTOOPT; | 3838 | retval = -ENOPROTOOPT; |
3730 | break; | 3839 | break; |
@@ -3971,6 +4080,9 @@ static int sctp_init_sock(struct sock *sk) | |||
3971 | /* Enable Nagle algorithm by default. */ | 4080 | /* Enable Nagle algorithm by default. */ |
3972 | sp->nodelay = 0; | 4081 | sp->nodelay = 0; |
3973 | 4082 | ||
4083 | sp->recvrcvinfo = 0; | ||
4084 | sp->recvnxtinfo = 0; | ||
4085 | |||
3974 | /* Enable by default. */ | 4086 | /* Enable by default. */ |
3975 | sp->v4mapped = 1; | 4087 | sp->v4mapped = 1; |
3976 | 4088 | ||
@@ -4131,7 +4243,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4131 | transport = asoc->peer.primary_path; | 4243 | transport = asoc->peer.primary_path; |
4132 | 4244 | ||
4133 | status.sstat_assoc_id = sctp_assoc2id(asoc); | 4245 | status.sstat_assoc_id = sctp_assoc2id(asoc); |
4134 | status.sstat_state = asoc->state; | 4246 | status.sstat_state = sctp_assoc_to_state(asoc); |
4135 | status.sstat_rwnd = asoc->peer.rwnd; | 4247 | status.sstat_rwnd = asoc->peer.rwnd; |
4136 | status.sstat_unackdata = asoc->unack_data; | 4248 | status.sstat_unackdata = asoc->unack_data; |
4137 | 4249 | ||
@@ -4143,7 +4255,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4143 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, | 4255 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, |
4144 | transport->af_specific->sockaddr_len); | 4256 | transport->af_specific->sockaddr_len); |
4145 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | 4257 | /* Map ipv4 address into v4-mapped-on-v6 address. */ |
4146 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 4258 | sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk), |
4147 | (union sctp_addr *)&status.sstat_primary.spinfo_address); | 4259 | (union sctp_addr *)&status.sstat_primary.spinfo_address); |
4148 | status.sstat_primary.spinfo_state = transport->state; | 4260 | status.sstat_primary.spinfo_state = transport->state; |
4149 | status.sstat_primary.spinfo_cwnd = transport->cwnd; | 4261 | status.sstat_primary.spinfo_cwnd = transport->cwnd; |
@@ -4301,8 +4413,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv | |||
4301 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | 4413 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) |
4302 | { | 4414 | { |
4303 | struct sctp_association *asoc = sctp_id2assoc(sk, id); | 4415 | struct sctp_association *asoc = sctp_id2assoc(sk, id); |
4416 | struct sctp_sock *sp = sctp_sk(sk); | ||
4304 | struct socket *sock; | 4417 | struct socket *sock; |
4305 | struct sctp_af *af; | ||
4306 | int err = 0; | 4418 | int err = 0; |
4307 | 4419 | ||
4308 | if (!asoc) | 4420 | if (!asoc) |
@@ -4324,8 +4436,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | |||
4324 | /* Make peeled-off sockets more like 1-1 accepted sockets. | 4436 | /* Make peeled-off sockets more like 1-1 accepted sockets. |
4325 | * Set the daddr and initialize id to something more random | 4437 | * Set the daddr and initialize id to something more random |
4326 | */ | 4438 | */ |
4327 | af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); | 4439 | sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk); |
4328 | af->to_sk_daddr(&asoc->peer.primary_addr, sk); | ||
4329 | 4440 | ||
4330 | /* Populate the fields of the newsk from the oldsk and migrate the | 4441 | /* Populate the fields of the newsk from the oldsk and migrate the |
4331 | * asoc to the newsk. | 4442 | * asoc to the newsk. |
@@ -4709,8 +4820,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
4709 | list_for_each_entry(from, &asoc->peer.transport_addr_list, | 4820 | list_for_each_entry(from, &asoc->peer.transport_addr_list, |
4710 | transports) { | 4821 | transports) { |
4711 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | 4822 | memcpy(&temp, &from->ipaddr, sizeof(temp)); |
4712 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4823 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4713 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4824 | ->addr_to_user(sp, &temp); |
4714 | if (space_left < addrlen) | 4825 | if (space_left < addrlen) |
4715 | return -ENOMEM; | 4826 | return -ENOMEM; |
4716 | if (copy_to_user(to, &temp, addrlen)) | 4827 | if (copy_to_user(to, &temp, addrlen)) |
@@ -4754,9 +4865,9 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
4754 | if (!temp.v4.sin_port) | 4865 | if (!temp.v4.sin_port) |
4755 | temp.v4.sin_port = htons(port); | 4866 | temp.v4.sin_port = htons(port); |
4756 | 4867 | ||
4757 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 4868 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4758 | &temp); | 4869 | ->addr_to_user(sctp_sk(sk), &temp); |
4759 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4870 | |
4760 | if (space_left < addrlen) { | 4871 | if (space_left < addrlen) { |
4761 | cnt = -ENOMEM; | 4872 | cnt = -ENOMEM; |
4762 | break; | 4873 | break; |
@@ -4844,8 +4955,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4844 | */ | 4955 | */ |
4845 | list_for_each_entry(addr, &bp->address_list, list) { | 4956 | list_for_each_entry(addr, &bp->address_list, list) { |
4846 | memcpy(&temp, &addr->a, sizeof(temp)); | 4957 | memcpy(&temp, &addr->a, sizeof(temp)); |
4847 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4958 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4848 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4959 | ->addr_to_user(sp, &temp); |
4849 | if (space_left < addrlen) { | 4960 | if (space_left < addrlen) { |
4850 | err = -ENOMEM; /*fixme: right error?*/ | 4961 | err = -ENOMEM; /*fixme: right error?*/ |
4851 | goto out; | 4962 | goto out; |
@@ -4904,7 +5015,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
4904 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, | 5015 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, |
4905 | asoc->peer.primary_path->af_specific->sockaddr_len); | 5016 | asoc->peer.primary_path->af_specific->sockaddr_len); |
4906 | 5017 | ||
4907 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, | 5018 | sctp_get_pf_specific(sk->sk_family)->addr_to_user(sp, |
4908 | (union sctp_addr *)&prim.ssp_addr); | 5019 | (union sctp_addr *)&prim.ssp_addr); |
4909 | 5020 | ||
4910 | if (put_user(len, optlen)) | 5021 | if (put_user(len, optlen)) |
@@ -4964,14 +5075,14 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
4964 | int len, char __user *optval, | 5075 | int len, char __user *optval, |
4965 | int __user *optlen) | 5076 | int __user *optlen) |
4966 | { | 5077 | { |
4967 | struct sctp_sndrcvinfo info; | ||
4968 | struct sctp_association *asoc; | ||
4969 | struct sctp_sock *sp = sctp_sk(sk); | 5078 | struct sctp_sock *sp = sctp_sk(sk); |
5079 | struct sctp_association *asoc; | ||
5080 | struct sctp_sndrcvinfo info; | ||
4970 | 5081 | ||
4971 | if (len < sizeof(struct sctp_sndrcvinfo)) | 5082 | if (len < sizeof(info)) |
4972 | return -EINVAL; | 5083 | return -EINVAL; |
4973 | 5084 | ||
4974 | len = sizeof(struct sctp_sndrcvinfo); | 5085 | len = sizeof(info); |
4975 | 5086 | ||
4976 | if (copy_from_user(&info, optval, len)) | 5087 | if (copy_from_user(&info, optval, len)) |
4977 | return -EFAULT; | 5088 | return -EFAULT; |
@@ -4979,7 +5090,6 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
4979 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | 5090 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); |
4980 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) | 5091 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) |
4981 | return -EINVAL; | 5092 | return -EINVAL; |
4982 | |||
4983 | if (asoc) { | 5093 | if (asoc) { |
4984 | info.sinfo_stream = asoc->default_stream; | 5094 | info.sinfo_stream = asoc->default_stream; |
4985 | info.sinfo_flags = asoc->default_flags; | 5095 | info.sinfo_flags = asoc->default_flags; |
@@ -5002,6 +5112,48 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
5002 | return 0; | 5112 | return 0; |
5003 | } | 5113 | } |
5004 | 5114 | ||
5115 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | ||
5116 | * (SCTP_DEFAULT_SNDINFO) | ||
5117 | */ | ||
5118 | static int sctp_getsockopt_default_sndinfo(struct sock *sk, int len, | ||
5119 | char __user *optval, | ||
5120 | int __user *optlen) | ||
5121 | { | ||
5122 | struct sctp_sock *sp = sctp_sk(sk); | ||
5123 | struct sctp_association *asoc; | ||
5124 | struct sctp_sndinfo info; | ||
5125 | |||
5126 | if (len < sizeof(info)) | ||
5127 | return -EINVAL; | ||
5128 | |||
5129 | len = sizeof(info); | ||
5130 | |||
5131 | if (copy_from_user(&info, optval, len)) | ||
5132 | return -EFAULT; | ||
5133 | |||
5134 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | ||
5135 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)) | ||
5136 | return -EINVAL; | ||
5137 | if (asoc) { | ||
5138 | info.snd_sid = asoc->default_stream; | ||
5139 | info.snd_flags = asoc->default_flags; | ||
5140 | info.snd_ppid = asoc->default_ppid; | ||
5141 | info.snd_context = asoc->default_context; | ||
5142 | } else { | ||
5143 | info.snd_sid = sp->default_stream; | ||
5144 | info.snd_flags = sp->default_flags; | ||
5145 | info.snd_ppid = sp->default_ppid; | ||
5146 | info.snd_context = sp->default_context; | ||
5147 | } | ||
5148 | |||
5149 | if (put_user(len, optlen)) | ||
5150 | return -EFAULT; | ||
5151 | if (copy_to_user(optval, &info, len)) | ||
5152 | return -EFAULT; | ||
5153 | |||
5154 | return 0; | ||
5155 | } | ||
5156 | |||
5005 | /* | 5157 | /* |
5006 | * | 5158 | * |
5007 | * 7.1.5 SCTP_NODELAY | 5159 | * 7.1.5 SCTP_NODELAY |
@@ -5752,6 +5904,46 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len, | |||
5752 | return 0; | 5904 | return 0; |
5753 | } | 5905 | } |
5754 | 5906 | ||
5907 | static int sctp_getsockopt_recvrcvinfo(struct sock *sk, int len, | ||
5908 | char __user *optval, | ||
5909 | int __user *optlen) | ||
5910 | { | ||
5911 | int val = 0; | ||
5912 | |||
5913 | if (len < sizeof(int)) | ||
5914 | return -EINVAL; | ||
5915 | |||
5916 | len = sizeof(int); | ||
5917 | if (sctp_sk(sk)->recvrcvinfo) | ||
5918 | val = 1; | ||
5919 | if (put_user(len, optlen)) | ||
5920 | return -EFAULT; | ||
5921 | if (copy_to_user(optval, &val, len)) | ||
5922 | return -EFAULT; | ||
5923 | |||
5924 | return 0; | ||
5925 | } | ||
5926 | |||
5927 | static int sctp_getsockopt_recvnxtinfo(struct sock *sk, int len, | ||
5928 | char __user *optval, | ||
5929 | int __user *optlen) | ||
5930 | { | ||
5931 | int val = 0; | ||
5932 | |||
5933 | if (len < sizeof(int)) | ||
5934 | return -EINVAL; | ||
5935 | |||
5936 | len = sizeof(int); | ||
5937 | if (sctp_sk(sk)->recvnxtinfo) | ||
5938 | val = 1; | ||
5939 | if (put_user(len, optlen)) | ||
5940 | return -EFAULT; | ||
5941 | if (copy_to_user(optval, &val, len)) | ||
5942 | return -EFAULT; | ||
5943 | |||
5944 | return 0; | ||
5945 | } | ||
5946 | |||
5755 | static int sctp_getsockopt(struct sock *sk, int level, int optname, | 5947 | static int sctp_getsockopt(struct sock *sk, int level, int optname, |
5756 | char __user *optval, int __user *optlen) | 5948 | char __user *optval, int __user *optlen) |
5757 | { | 5949 | { |
@@ -5821,6 +6013,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5821 | retval = sctp_getsockopt_default_send_param(sk, len, | 6013 | retval = sctp_getsockopt_default_send_param(sk, len, |
5822 | optval, optlen); | 6014 | optval, optlen); |
5823 | break; | 6015 | break; |
6016 | case SCTP_DEFAULT_SNDINFO: | ||
6017 | retval = sctp_getsockopt_default_sndinfo(sk, len, | ||
6018 | optval, optlen); | ||
6019 | break; | ||
5824 | case SCTP_PRIMARY_ADDR: | 6020 | case SCTP_PRIMARY_ADDR: |
5825 | retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); | 6021 | retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); |
5826 | break; | 6022 | break; |
@@ -5895,6 +6091,12 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5895 | case SCTP_GET_ASSOC_STATS: | 6091 | case SCTP_GET_ASSOC_STATS: |
5896 | retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); | 6092 | retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); |
5897 | break; | 6093 | break; |
6094 | case SCTP_RECVRCVINFO: | ||
6095 | retval = sctp_getsockopt_recvrcvinfo(sk, len, optval, optlen); | ||
6096 | break; | ||
6097 | case SCTP_RECVNXTINFO: | ||
6098 | retval = sctp_getsockopt_recvnxtinfo(sk, len, optval, optlen); | ||
6099 | break; | ||
5898 | default: | 6100 | default: |
5899 | retval = -ENOPROTOOPT; | 6101 | retval = -ENOPROTOOPT; |
5900 | break; | 6102 | break; |
@@ -6390,8 +6592,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6390 | struct cmsghdr *cmsg; | 6592 | struct cmsghdr *cmsg; |
6391 | struct msghdr *my_msg = (struct msghdr *)msg; | 6593 | struct msghdr *my_msg = (struct msghdr *)msg; |
6392 | 6594 | ||
6393 | for (cmsg = CMSG_FIRSTHDR(msg); | 6595 | for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; |
6394 | cmsg != NULL; | ||
6395 | cmsg = CMSG_NXTHDR(my_msg, cmsg)) { | 6596 | cmsg = CMSG_NXTHDR(my_msg, cmsg)) { |
6396 | if (!CMSG_OK(my_msg, cmsg)) | 6597 | if (!CMSG_OK(my_msg, cmsg)) |
6397 | return -EINVAL; | 6598 | return -EINVAL; |
@@ -6404,7 +6605,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6404 | switch (cmsg->cmsg_type) { | 6605 | switch (cmsg->cmsg_type) { |
6405 | case SCTP_INIT: | 6606 | case SCTP_INIT: |
6406 | /* SCTP Socket API Extension | 6607 | /* SCTP Socket API Extension |
6407 | * 5.2.1 SCTP Initiation Structure (SCTP_INIT) | 6608 | * 5.3.1 SCTP Initiation Structure (SCTP_INIT) |
6408 | * | 6609 | * |
6409 | * This cmsghdr structure provides information for | 6610 | * This cmsghdr structure provides information for |
6410 | * initializing new SCTP associations with sendmsg(). | 6611 | * initializing new SCTP associations with sendmsg(). |
@@ -6416,15 +6617,15 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6416 | * ------------ ------------ ---------------------- | 6617 | * ------------ ------------ ---------------------- |
6417 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg | 6618 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg |
6418 | */ | 6619 | */ |
6419 | if (cmsg->cmsg_len != | 6620 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_initmsg))) |
6420 | CMSG_LEN(sizeof(struct sctp_initmsg))) | ||
6421 | return -EINVAL; | 6621 | return -EINVAL; |
6422 | cmsgs->init = (struct sctp_initmsg *)CMSG_DATA(cmsg); | 6622 | |
6623 | cmsgs->init = CMSG_DATA(cmsg); | ||
6423 | break; | 6624 | break; |
6424 | 6625 | ||
6425 | case SCTP_SNDRCV: | 6626 | case SCTP_SNDRCV: |
6426 | /* SCTP Socket API Extension | 6627 | /* SCTP Socket API Extension |
6427 | * 5.2.2 SCTP Header Information Structure(SCTP_SNDRCV) | 6628 | * 5.3.2 SCTP Header Information Structure(SCTP_SNDRCV) |
6428 | * | 6629 | * |
6429 | * This cmsghdr structure specifies SCTP options for | 6630 | * This cmsghdr structure specifies SCTP options for |
6430 | * sendmsg() and describes SCTP header information | 6631 | * sendmsg() and describes SCTP header information |
@@ -6434,24 +6635,44 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6434 | * ------------ ------------ ---------------------- | 6635 | * ------------ ------------ ---------------------- |
6435 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo | 6636 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo |
6436 | */ | 6637 | */ |
6437 | if (cmsg->cmsg_len != | 6638 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndrcvinfo))) |
6438 | CMSG_LEN(sizeof(struct sctp_sndrcvinfo))) | ||
6439 | return -EINVAL; | 6639 | return -EINVAL; |
6440 | 6640 | ||
6441 | cmsgs->info = | 6641 | cmsgs->srinfo = CMSG_DATA(cmsg); |
6442 | (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | ||
6443 | 6642 | ||
6444 | /* Minimally, validate the sinfo_flags. */ | 6643 | if (cmsgs->srinfo->sinfo_flags & |
6445 | if (cmsgs->info->sinfo_flags & | ||
6446 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | 6644 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | |
6447 | SCTP_ABORT | SCTP_EOF)) | 6645 | SCTP_ABORT | SCTP_EOF)) |
6448 | return -EINVAL; | 6646 | return -EINVAL; |
6449 | break; | 6647 | break; |
6450 | 6648 | ||
6649 | case SCTP_SNDINFO: | ||
6650 | /* SCTP Socket API Extension | ||
6651 | * 5.3.4 SCTP Send Information Structure (SCTP_SNDINFO) | ||
6652 | * | ||
6653 | * This cmsghdr structure specifies SCTP options for | ||
6654 | * sendmsg(). This structure and SCTP_RCVINFO replaces | ||
6655 | * SCTP_SNDRCV which has been deprecated. | ||
6656 | * | ||
6657 | * cmsg_level cmsg_type cmsg_data[] | ||
6658 | * ------------ ------------ --------------------- | ||
6659 | * IPPROTO_SCTP SCTP_SNDINFO struct sctp_sndinfo | ||
6660 | */ | ||
6661 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndinfo))) | ||
6662 | return -EINVAL; | ||
6663 | |||
6664 | cmsgs->sinfo = CMSG_DATA(cmsg); | ||
6665 | |||
6666 | if (cmsgs->sinfo->snd_flags & | ||
6667 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
6668 | SCTP_ABORT | SCTP_EOF)) | ||
6669 | return -EINVAL; | ||
6670 | break; | ||
6451 | default: | 6671 | default: |
6452 | return -EINVAL; | 6672 | return -EINVAL; |
6453 | } | 6673 | } |
6454 | } | 6674 | } |
6675 | |||
6455 | return 0; | 6676 | return 0; |
6456 | } | 6677 | } |
6457 | 6678 | ||
@@ -6518,8 +6739,8 @@ out: | |||
6518 | * Note: This is pretty much the same routine as in core/datagram.c | 6739 | * Note: This is pretty much the same routine as in core/datagram.c |
6519 | * with a few changes to make lksctp work. | 6740 | * with a few changes to make lksctp work. |
6520 | */ | 6741 | */ |
6521 | static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | 6742 | struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, |
6522 | int noblock, int *err) | 6743 | int noblock, int *err) |
6523 | { | 6744 | { |
6524 | int error; | 6745 | int error; |
6525 | struct sk_buff *skb; | 6746 | struct sk_buff *skb; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 12c7e01c2677..2e9ada10fd84 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -424,8 +424,9 @@ static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, | |||
424 | void __user *buffer, size_t *lenp, | 424 | void __user *buffer, size_t *lenp, |
425 | loff_t *ppos) | 425 | loff_t *ppos) |
426 | { | 426 | { |
427 | pr_warn_once("Changing rto_alpha or rto_beta may lead to " | 427 | if (write) |
428 | "suboptimal rtt/srtt estimations!\n"); | 428 | pr_warn_once("Changing rto_alpha or rto_beta may lead to " |
429 | "suboptimal rtt/srtt estimations!\n"); | ||
429 | 430 | ||
430 | return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); | 431 | return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); |
431 | } | 432 | } |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 7dd672fa651f..a0a431824f63 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -289,8 +289,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
289 | */ | 289 | */ |
290 | if (asoc && (!asoc->peer.primary_path || | 290 | if (asoc && (!asoc->peer.primary_path || |
291 | (transport == asoc->peer.active_path))) | 291 | (transport == asoc->peer.active_path))) |
292 | opt->pf->af->to_sk_saddr(&transport->saddr, | 292 | opt->pf->to_sk_saddr(&transport->saddr, |
293 | asoc->base.sk); | 293 | asoc->base.sk); |
294 | } else | 294 | } else |
295 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 295 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
296 | } | 296 | } |
@@ -594,15 +594,16 @@ void sctp_transport_burst_reset(struct sctp_transport *t) | |||
594 | } | 594 | } |
595 | 595 | ||
596 | /* What is the next timeout value for this transport? */ | 596 | /* What is the next timeout value for this transport? */ |
597 | unsigned long sctp_transport_timeout(struct sctp_transport *t) | 597 | unsigned long sctp_transport_timeout(struct sctp_transport *trans) |
598 | { | 598 | { |
599 | unsigned long timeout; | 599 | /* RTO + timer slack +/- 50% of RTO */ |
600 | timeout = t->rto + sctp_jitter(t->rto); | 600 | unsigned long timeout = (trans->rto >> 1) + prandom_u32_max(trans->rto); |
601 | if ((t->state != SCTP_UNCONFIRMED) && | 601 | |
602 | (t->state != SCTP_PF)) | 602 | if (trans->state != SCTP_UNCONFIRMED && |
603 | timeout += t->hbinterval; | 603 | trans->state != SCTP_PF) |
604 | timeout += jiffies; | 604 | timeout += trans->hbinterval; |
605 | return timeout; | 605 | |
606 | return timeout + jiffies; | ||
606 | } | 607 | } |
607 | 608 | ||
608 | /* Reset transport variables to their initial values */ | 609 | /* Reset transport variables to their initial values */ |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index b6842fdb53d4..d1e38308f615 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -341,7 +341,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( | |||
341 | memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage)); | 341 | memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage)); |
342 | 342 | ||
343 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | 343 | /* Map ipv4 address into v4-mapped-on-v6 address. */ |
344 | sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map( | 344 | sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_to_user( |
345 | sctp_sk(asoc->base.sk), | 345 | sctp_sk(asoc->base.sk), |
346 | (union sctp_addr *)&spc->spc_aaddr); | 346 | (union sctp_addr *)&spc->spc_aaddr); |
347 | 347 | ||
@@ -886,6 +886,69 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
886 | sizeof(sinfo), &sinfo); | 886 | sizeof(sinfo), &sinfo); |
887 | } | 887 | } |
888 | 888 | ||
889 | /* RFC6458, Section 5.3.5 SCTP Receive Information Structure | ||
890 | * (SCTP_SNDRCV) | ||
891 | */ | ||
892 | void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event, | ||
893 | struct msghdr *msghdr) | ||
894 | { | ||
895 | struct sctp_rcvinfo rinfo; | ||
896 | |||
897 | if (sctp_ulpevent_is_notification(event)) | ||
898 | return; | ||
899 | |||
900 | memset(&rinfo, 0, sizeof(struct sctp_rcvinfo)); | ||
901 | rinfo.rcv_sid = event->stream; | ||
902 | rinfo.rcv_ssn = event->ssn; | ||
903 | rinfo.rcv_ppid = event->ppid; | ||
904 | rinfo.rcv_flags = event->flags; | ||
905 | rinfo.rcv_tsn = event->tsn; | ||
906 | rinfo.rcv_cumtsn = event->cumtsn; | ||
907 | rinfo.rcv_assoc_id = sctp_assoc2id(event->asoc); | ||
908 | rinfo.rcv_context = event->asoc->default_rcv_context; | ||
909 | |||
910 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_RCVINFO, | ||
911 | sizeof(rinfo), &rinfo); | ||
912 | } | ||
913 | |||
914 | /* RFC6458, Section 5.3.6. SCTP Next Receive Information Structure | ||
915 | * (SCTP_NXTINFO) | ||
916 | */ | ||
917 | static void __sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event, | ||
918 | struct msghdr *msghdr, | ||
919 | const struct sk_buff *skb) | ||
920 | { | ||
921 | struct sctp_nxtinfo nxtinfo; | ||
922 | |||
923 | memset(&nxtinfo, 0, sizeof(nxtinfo)); | ||
924 | nxtinfo.nxt_sid = event->stream; | ||
925 | nxtinfo.nxt_ppid = event->ppid; | ||
926 | nxtinfo.nxt_flags = event->flags; | ||
927 | if (sctp_ulpevent_is_notification(event)) | ||
928 | nxtinfo.nxt_flags |= SCTP_NOTIFICATION; | ||
929 | nxtinfo.nxt_length = skb->len; | ||
930 | nxtinfo.nxt_assoc_id = sctp_assoc2id(event->asoc); | ||
931 | |||
932 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_NXTINFO, | ||
933 | sizeof(nxtinfo), &nxtinfo); | ||
934 | } | ||
935 | |||
936 | void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event, | ||
937 | struct msghdr *msghdr, | ||
938 | struct sock *sk) | ||
939 | { | ||
940 | struct sk_buff *skb; | ||
941 | int err; | ||
942 | |||
943 | skb = sctp_skb_recv_datagram(sk, MSG_PEEK, 1, &err); | ||
944 | if (skb != NULL) { | ||
945 | __sctp_ulpevent_read_nxtinfo(sctp_skb2event(skb), | ||
946 | msghdr, skb); | ||
947 | /* Just release refcount here. */ | ||
948 | kfree_skb(skb); | ||
949 | } | ||
950 | } | ||
951 | |||
889 | /* Do accounting for bytes received and hold a reference to the association | 952 | /* Do accounting for bytes received and hold a reference to the association |
890 | * for each skb. | 953 | * for each skb. |
891 | */ | 954 | */ |