summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-11-07 04:32:44 -0500
committerIngo Molnar <mingo@kernel.org>2017-11-07 04:32:44 -0500
commit8c5db92a705d9e2c986adec475980d1120fa07b4 (patch)
tree9f0eea56889819707c0a1a8eb5b1fb2db3cdaf3d /net/sctp
parentca5d376e17072c1b60c3fee66f3be58ef018952d (diff)
parente4880bc5dfb1f02b152e62a894b5c6f3e995b3cf (diff)
Merge branch 'linus' into locking/core, to resolve conflicts
Conflicts: include/linux/compiler-clang.h include/linux/compiler-gcc.h include/linux/compiler-intel.h include/uapi/linux/stddef.h Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/Makefile1
-rw-r--r--net/sctp/input.c22
-rw-r--r--net/sctp/ipv6.c8
-rw-r--r--net/sctp/sm_make_chunk.c9
-rw-r--r--net/sctp/sm_sideeffect.c8
-rw-r--r--net/sctp/socket.c32
-rw-r--r--net/sctp/stream.c26
-rw-r--r--net/sctp/ulpevent.c2
8 files changed, 76 insertions, 32 deletions
diff --git a/net/sctp/Makefile b/net/sctp/Makefile
index 70f1b570bab9..8c434af3e68f 100644
--- a/net/sctp/Makefile
+++ b/net/sctp/Makefile
@@ -1,3 +1,4 @@
1# SPDX-License-Identifier: GPL-2.0
1# 2#
2# Makefile for SCTP support code. 3# Makefile for SCTP support code.
3# 4#
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 34f10e75f3b9..621b5ca3fd1c 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -794,7 +794,7 @@ hit:
794struct sctp_hash_cmp_arg { 794struct sctp_hash_cmp_arg {
795 const union sctp_addr *paddr; 795 const union sctp_addr *paddr;
796 const struct net *net; 796 const struct net *net;
797 u16 lport; 797 __be16 lport;
798}; 798};
799 799
800static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, 800static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg,
@@ -820,37 +820,37 @@ out:
820 return err; 820 return err;
821} 821}
822 822
823static inline u32 sctp_hash_obj(const void *data, u32 len, u32 seed) 823static inline __u32 sctp_hash_obj(const void *data, u32 len, u32 seed)
824{ 824{
825 const struct sctp_transport *t = data; 825 const struct sctp_transport *t = data;
826 const union sctp_addr *paddr = &t->ipaddr; 826 const union sctp_addr *paddr = &t->ipaddr;
827 const struct net *net = sock_net(t->asoc->base.sk); 827 const struct net *net = sock_net(t->asoc->base.sk);
828 u16 lport = htons(t->asoc->base.bind_addr.port); 828 __be16 lport = htons(t->asoc->base.bind_addr.port);
829 u32 addr; 829 __u32 addr;
830 830
831 if (paddr->sa.sa_family == AF_INET6) 831 if (paddr->sa.sa_family == AF_INET6)
832 addr = jhash(&paddr->v6.sin6_addr, 16, seed); 832 addr = jhash(&paddr->v6.sin6_addr, 16, seed);
833 else 833 else
834 addr = paddr->v4.sin_addr.s_addr; 834 addr = (__force __u32)paddr->v4.sin_addr.s_addr;
835 835
836 return jhash_3words(addr, ((__u32)paddr->v4.sin_port) << 16 | 836 return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 |
837 (__force __u32)lport, net_hash_mix(net), seed); 837 (__force __u32)lport, net_hash_mix(net), seed);
838} 838}
839 839
840static inline u32 sctp_hash_key(const void *data, u32 len, u32 seed) 840static inline __u32 sctp_hash_key(const void *data, u32 len, u32 seed)
841{ 841{
842 const struct sctp_hash_cmp_arg *x = data; 842 const struct sctp_hash_cmp_arg *x = data;
843 const union sctp_addr *paddr = x->paddr; 843 const union sctp_addr *paddr = x->paddr;
844 const struct net *net = x->net; 844 const struct net *net = x->net;
845 u16 lport = x->lport; 845 __be16 lport = x->lport;
846 u32 addr; 846 __u32 addr;
847 847
848 if (paddr->sa.sa_family == AF_INET6) 848 if (paddr->sa.sa_family == AF_INET6)
849 addr = jhash(&paddr->v6.sin6_addr, 16, seed); 849 addr = jhash(&paddr->v6.sin6_addr, 16, seed);
850 else 850 else
851 addr = paddr->v4.sin_addr.s_addr; 851 addr = (__force __u32)paddr->v4.sin_addr.s_addr;
852 852
853 return jhash_3words(addr, ((__u32)paddr->v4.sin_port) << 16 | 853 return jhash_3words(addr, ((__force __u32)paddr->v4.sin_port) << 16 |
854 (__force __u32)lport, net_hash_mix(net), seed); 854 (__force __u32)lport, net_hash_mix(net), seed);
855} 855}
856 856
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 51c488769590..a6dfa86c0201 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -738,7 +738,7 @@ static int sctp_v6_skb_iif(const struct sk_buff *skb)
738/* Was this packet marked by Explicit Congestion Notification? */ 738/* Was this packet marked by Explicit Congestion Notification? */
739static int sctp_v6_is_ce(const struct sk_buff *skb) 739static int sctp_v6_is_ce(const struct sk_buff *skb)
740{ 740{
741 return *((__u32 *)(ipv6_hdr(skb))) & htonl(1 << 20); 741 return *((__u32 *)(ipv6_hdr(skb))) & (__force __u32)htonl(1 << 20);
742} 742}
743 743
744/* Dump the v6 addr to the seq file. */ 744/* Dump the v6 addr to the seq file. */
@@ -882,8 +882,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
882 net = sock_net(&opt->inet.sk); 882 net = sock_net(&opt->inet.sk);
883 rcu_read_lock(); 883 rcu_read_lock();
884 dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id); 884 dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id);
885 if (!dev || 885 if (!dev || !(opt->inet.freebind ||
886 !ipv6_chk_addr(net, &addr->v6.sin6_addr, dev, 0)) { 886 net->ipv6.sysctl.ip_nonlocal_bind ||
887 ipv6_chk_addr(net, &addr->v6.sin6_addr,
888 dev, 0))) {
887 rcu_read_unlock(); 889 rcu_read_unlock();
888 return 0; 890 return 0;
889 } 891 }
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index ca8f196b6c6c..514465b03829 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2854,7 +2854,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2854 addr_param_len = af->to_addr_param(addr, &addr_param); 2854 addr_param_len = af->to_addr_param(addr, &addr_param);
2855 param.param_hdr.type = flags; 2855 param.param_hdr.type = flags;
2856 param.param_hdr.length = htons(paramlen + addr_param_len); 2856 param.param_hdr.length = htons(paramlen + addr_param_len);
2857 param.crr_id = i; 2857 param.crr_id = htonl(i);
2858 2858
2859 sctp_addto_chunk(retval, paramlen, &param); 2859 sctp_addto_chunk(retval, paramlen, &param);
2860 sctp_addto_chunk(retval, addr_param_len, &addr_param); 2860 sctp_addto_chunk(retval, addr_param_len, &addr_param);
@@ -2867,7 +2867,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2867 addr_param_len = af->to_addr_param(addr, &addr_param); 2867 addr_param_len = af->to_addr_param(addr, &addr_param);
2868 param.param_hdr.type = SCTP_PARAM_DEL_IP; 2868 param.param_hdr.type = SCTP_PARAM_DEL_IP;
2869 param.param_hdr.length = htons(paramlen + addr_param_len); 2869 param.param_hdr.length = htons(paramlen + addr_param_len);
2870 param.crr_id = i; 2870 param.crr_id = htonl(i);
2871 2871
2872 sctp_addto_chunk(retval, paramlen, &param); 2872 sctp_addto_chunk(retval, paramlen, &param);
2873 sctp_addto_chunk(retval, addr_param_len, &addr_param); 2873 sctp_addto_chunk(retval, addr_param_len, &addr_param);
@@ -3591,7 +3591,7 @@ static struct sctp_chunk *sctp_make_reconf(const struct sctp_association *asoc,
3591 */ 3591 */
3592struct sctp_chunk *sctp_make_strreset_req( 3592struct sctp_chunk *sctp_make_strreset_req(
3593 const struct sctp_association *asoc, 3593 const struct sctp_association *asoc,
3594 __u16 stream_num, __u16 *stream_list, 3594 __u16 stream_num, __be16 *stream_list,
3595 bool out, bool in) 3595 bool out, bool in)
3596{ 3596{
3597 struct sctp_strreset_outreq outreq; 3597 struct sctp_strreset_outreq outreq;
@@ -3788,7 +3788,8 @@ bool sctp_verify_reconf(const struct sctp_association *asoc,
3788{ 3788{
3789 struct sctp_reconf_chunk *hdr; 3789 struct sctp_reconf_chunk *hdr;
3790 union sctp_params param; 3790 union sctp_params param;
3791 __u16 last = 0, cnt = 0; 3791 __be16 last = 0;
3792 __u16 cnt = 0;
3792 3793
3793 hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr; 3794 hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
3794 sctp_walk_params(param, hdr, params) { 3795 sctp_walk_params(param, hdr, params) {
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index e6a2974e020e..e2d9a4b49c9c 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1607,12 +1607,12 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
1607 break; 1607 break;
1608 1608
1609 case SCTP_CMD_INIT_FAILED: 1609 case SCTP_CMD_INIT_FAILED:
1610 sctp_cmd_init_failed(commands, asoc, cmd->obj.err); 1610 sctp_cmd_init_failed(commands, asoc, cmd->obj.u32);
1611 break; 1611 break;
1612 1612
1613 case SCTP_CMD_ASSOC_FAILED: 1613 case SCTP_CMD_ASSOC_FAILED:
1614 sctp_cmd_assoc_failed(commands, asoc, event_type, 1614 sctp_cmd_assoc_failed(commands, asoc, event_type,
1615 subtype, chunk, cmd->obj.err); 1615 subtype, chunk, cmd->obj.u32);
1616 break; 1616 break;
1617 1617
1618 case SCTP_CMD_INIT_COUNTER_INC: 1618 case SCTP_CMD_INIT_COUNTER_INC:
@@ -1680,8 +1680,8 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
1680 case SCTP_CMD_PROCESS_CTSN: 1680 case SCTP_CMD_PROCESS_CTSN:
1681 /* Dummy up a SACK for processing. */ 1681 /* Dummy up a SACK for processing. */
1682 sackh.cum_tsn_ack = cmd->obj.be32; 1682 sackh.cum_tsn_ack = cmd->obj.be32;
1683 sackh.a_rwnd = asoc->peer.rwnd + 1683 sackh.a_rwnd = htonl(asoc->peer.rwnd +
1684 asoc->outqueue.outstanding_bytes; 1684 asoc->outqueue.outstanding_bytes);
1685 sackh.num_gap_ack_blocks = 0; 1685 sackh.num_gap_ack_blocks = 0;
1686 sackh.num_dup_tsns = 0; 1686 sackh.num_dup_tsns = 0;
1687 chunk->subh.sack_hdr = &sackh; 1687 chunk->subh.sack_hdr = &sackh;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 17841ab30798..6f45d1713452 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -170,6 +170,36 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
170 sk_mem_charge(sk, chunk->skb->truesize); 170 sk_mem_charge(sk, chunk->skb->truesize);
171} 171}
172 172
173static void sctp_clear_owner_w(struct sctp_chunk *chunk)
174{
175 skb_orphan(chunk->skb);
176}
177
178static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
179 void (*cb)(struct sctp_chunk *))
180
181{
182 struct sctp_outq *q = &asoc->outqueue;
183 struct sctp_transport *t;
184 struct sctp_chunk *chunk;
185
186 list_for_each_entry(t, &asoc->peer.transport_addr_list, transports)
187 list_for_each_entry(chunk, &t->transmitted, transmitted_list)
188 cb(chunk);
189
190 list_for_each_entry(chunk, &q->retransmit, list)
191 cb(chunk);
192
193 list_for_each_entry(chunk, &q->sacked, list)
194 cb(chunk);
195
196 list_for_each_entry(chunk, &q->abandoned, list)
197 cb(chunk);
198
199 list_for_each_entry(chunk, &q->out_chunk_list, list)
200 cb(chunk);
201}
202
173/* Verify that this is a valid address. */ 203/* Verify that this is a valid address. */
174static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, 204static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
175 int len) 205 int len)
@@ -8212,7 +8242,9 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
8212 * paths won't try to lock it and then oldsk. 8242 * paths won't try to lock it and then oldsk.
8213 */ 8243 */
8214 lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); 8244 lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
8245 sctp_for_each_tx_datachunk(assoc, sctp_clear_owner_w);
8215 sctp_assoc_migrate(assoc, newsk); 8246 sctp_assoc_migrate(assoc, newsk);
8247 sctp_for_each_tx_datachunk(assoc, sctp_set_owner_w);
8216 8248
8217 /* If the association on the newsk is already closed before accept() 8249 /* If the association on the newsk is already closed before accept()
8218 * is called, set RCV_SHUTDOWN flag. 8250 * is called, set RCV_SHUTDOWN flag.
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 63ea15503714..fa8371ff05c4 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -118,6 +118,7 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
118 __u16 i, str_nums, *str_list; 118 __u16 i, str_nums, *str_list;
119 struct sctp_chunk *chunk; 119 struct sctp_chunk *chunk;
120 int retval = -EINVAL; 120 int retval = -EINVAL;
121 __be16 *nstr_list;
121 bool out, in; 122 bool out, in;
122 123
123 if (!asoc->peer.reconf_capable || 124 if (!asoc->peer.reconf_capable ||
@@ -148,13 +149,18 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
148 if (str_list[i] >= stream->incnt) 149 if (str_list[i] >= stream->incnt)
149 goto out; 150 goto out;
150 151
152 nstr_list = kcalloc(str_nums, sizeof(__be16), GFP_KERNEL);
153 if (!nstr_list) {
154 retval = -ENOMEM;
155 goto out;
156 }
157
151 for (i = 0; i < str_nums; i++) 158 for (i = 0; i < str_nums; i++)
152 str_list[i] = htons(str_list[i]); 159 nstr_list[i] = htons(str_list[i]);
153 160
154 chunk = sctp_make_strreset_req(asoc, str_nums, str_list, out, in); 161 chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in);
155 162
156 for (i = 0; i < str_nums; i++) 163 kfree(nstr_list);
157 str_list[i] = ntohs(str_list[i]);
158 164
159 if (!chunk) { 165 if (!chunk) {
160 retval = -ENOMEM; 166 retval = -ENOMEM;
@@ -305,7 +311,7 @@ out:
305} 311}
306 312
307static struct sctp_paramhdr *sctp_chunk_lookup_strreset_param( 313static struct sctp_paramhdr *sctp_chunk_lookup_strreset_param(
308 struct sctp_association *asoc, __u32 resp_seq, 314 struct sctp_association *asoc, __be32 resp_seq,
309 __be16 type) 315 __be16 type)
310{ 316{
311 struct sctp_chunk *chunk = asoc->strreset_chunk; 317 struct sctp_chunk *chunk = asoc->strreset_chunk;
@@ -345,8 +351,9 @@ struct sctp_chunk *sctp_process_strreset_outreq(
345{ 351{
346 struct sctp_strreset_outreq *outreq = param.v; 352 struct sctp_strreset_outreq *outreq = param.v;
347 struct sctp_stream *stream = &asoc->stream; 353 struct sctp_stream *stream = &asoc->stream;
348 __u16 i, nums, flags = 0, *str_p = NULL;
349 __u32 result = SCTP_STRRESET_DENIED; 354 __u32 result = SCTP_STRRESET_DENIED;
355 __u16 i, nums, flags = 0;
356 __be16 *str_p = NULL;
350 __u32 request_seq; 357 __u32 request_seq;
351 358
352 request_seq = ntohl(outreq->request_seq); 359 request_seq = ntohl(outreq->request_seq);
@@ -439,8 +446,9 @@ struct sctp_chunk *sctp_process_strreset_inreq(
439 struct sctp_stream *stream = &asoc->stream; 446 struct sctp_stream *stream = &asoc->stream;
440 __u32 result = SCTP_STRRESET_DENIED; 447 __u32 result = SCTP_STRRESET_DENIED;
441 struct sctp_chunk *chunk = NULL; 448 struct sctp_chunk *chunk = NULL;
442 __u16 i, nums, *str_p;
443 __u32 request_seq; 449 __u32 request_seq;
450 __u16 i, nums;
451 __be16 *str_p;
444 452
445 request_seq = ntohl(inreq->request_seq); 453 request_seq = ntohl(inreq->request_seq);
446 if (TSN_lt(asoc->strreset_inseq, request_seq) || 454 if (TSN_lt(asoc->strreset_inseq, request_seq) ||
@@ -769,7 +777,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
769 777
770 if (req->type == SCTP_PARAM_RESET_OUT_REQUEST) { 778 if (req->type == SCTP_PARAM_RESET_OUT_REQUEST) {
771 struct sctp_strreset_outreq *outreq; 779 struct sctp_strreset_outreq *outreq;
772 __u16 *str_p; 780 __be16 *str_p;
773 781
774 outreq = (struct sctp_strreset_outreq *)req; 782 outreq = (struct sctp_strreset_outreq *)req;
775 str_p = outreq->list_of_streams; 783 str_p = outreq->list_of_streams;
@@ -794,7 +802,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
794 nums, str_p, GFP_ATOMIC); 802 nums, str_p, GFP_ATOMIC);
795 } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) { 803 } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) {
796 struct sctp_strreset_inreq *inreq; 804 struct sctp_strreset_inreq *inreq;
797 __u16 *str_p; 805 __be16 *str_p;
798 806
799 /* if the result is performed, it's impossible for inreq */ 807 /* if the result is performed, it's impossible for inreq */
800 if (result == SCTP_STRRESET_PERFORMED) 808 if (result == SCTP_STRRESET_PERFORMED)
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 67abc0194f30..5447228bf1a0 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -847,7 +847,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
847 847
848struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event( 848struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event(
849 const struct sctp_association *asoc, __u16 flags, __u16 stream_num, 849 const struct sctp_association *asoc, __u16 flags, __u16 stream_num,
850 __u16 *stream_list, gfp_t gfp) 850 __be16 *stream_list, gfp_t gfp)
851{ 851{
852 struct sctp_stream_reset_event *sreset; 852 struct sctp_stream_reset_event *sreset;
853 struct sctp_ulpevent *event; 853 struct sctp_ulpevent *event;