diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-11-18 03:08:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-19 15:25:43 -0500 |
commit | a1e3a0590f9bd232f3a03fd87226a4a99bd5ec92 (patch) | |
tree | 297cba2473cc25cc11b9aa5d5bc49a3b6b3d9e81 | |
parent | 2cc0eeb67636e0339ad7b6cdfa305f63983642af (diff) |
sctp: add subscribe per asoc
The member subscribe should be per asoc, so that sockopt SCTP_EVENT
in the next patch can subscribe a event from one asoc only.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sctp/structs.h | 2 | ||||
-rw-r--r-- | net/sctp/associola.c | 2 | ||||
-rw-r--r-- | net/sctp/chunk.c | 6 | ||||
-rw-r--r-- | net/sctp/socket.c | 6 | ||||
-rw-r--r-- | net/sctp/stream_interleave.c | 7 | ||||
-rw-r--r-- | net/sctp/ulpqueue.c | 4 |
6 files changed, 17 insertions, 10 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index bc7808aa2760..7eaa294d938d 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -2077,6 +2077,8 @@ struct sctp_association { | |||
2077 | 2077 | ||
2078 | int sent_cnt_removable; | 2078 | int sent_cnt_removable; |
2079 | 2079 | ||
2080 | __u16 subscribe; | ||
2081 | |||
2080 | __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1]; | 2082 | __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1]; |
2081 | __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1]; | 2083 | __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1]; |
2082 | }; | 2084 | }; |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 6a28b96e779e..685c7ef11eb4 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -135,6 +135,8 @@ static struct sctp_association *sctp_association_init( | |||
135 | */ | 135 | */ |
136 | asoc->max_burst = sp->max_burst; | 136 | asoc->max_burst = sp->max_burst; |
137 | 137 | ||
138 | asoc->subscribe = sp->subscribe; | ||
139 | |||
138 | /* initialize association timers */ | 140 | /* initialize association timers */ |
139 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = asoc->rto_initial; | 141 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = asoc->rto_initial; |
140 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = asoc->rto_initial; | 142 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = asoc->rto_initial; |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 6c761af960fd..0b203b821709 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -86,11 +86,10 @@ void sctp_datamsg_free(struct sctp_datamsg *msg) | |||
86 | /* Final destructruction of datamsg memory. */ | 86 | /* Final destructruction of datamsg memory. */ |
87 | static void sctp_datamsg_destroy(struct sctp_datamsg *msg) | 87 | static void sctp_datamsg_destroy(struct sctp_datamsg *msg) |
88 | { | 88 | { |
89 | struct sctp_association *asoc = NULL; | ||
89 | struct list_head *pos, *temp; | 90 | struct list_head *pos, *temp; |
90 | struct sctp_chunk *chunk; | 91 | struct sctp_chunk *chunk; |
91 | struct sctp_sock *sp; | ||
92 | struct sctp_ulpevent *ev; | 92 | struct sctp_ulpevent *ev; |
93 | struct sctp_association *asoc = NULL; | ||
94 | int error = 0, notify; | 93 | int error = 0, notify; |
95 | 94 | ||
96 | /* If we failed, we may need to notify. */ | 95 | /* If we failed, we may need to notify. */ |
@@ -108,8 +107,7 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg) | |||
108 | else | 107 | else |
109 | error = asoc->outqueue.error; | 108 | error = asoc->outqueue.error; |
110 | 109 | ||
111 | sp = sctp_sk(asoc->base.sk); | 110 | notify = sctp_ulpevent_type_enabled(asoc->subscribe, |
112 | notify = sctp_ulpevent_type_enabled(sp->subscribe, | ||
113 | SCTP_SEND_FAILED); | 111 | SCTP_SEND_FAILED); |
114 | } | 112 | } |
115 | 113 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9d7512958a6a..c7718272d69b 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2307,6 +2307,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2307 | struct sctp_event_subscribe subscribe; | 2307 | struct sctp_event_subscribe subscribe; |
2308 | __u8 *sn_type = (__u8 *)&subscribe; | 2308 | __u8 *sn_type = (__u8 *)&subscribe; |
2309 | struct sctp_sock *sp = sctp_sk(sk); | 2309 | struct sctp_sock *sp = sctp_sk(sk); |
2310 | struct sctp_association *asoc; | ||
2310 | int i; | 2311 | int i; |
2311 | 2312 | ||
2312 | if (optlen > sizeof(struct sctp_event_subscribe)) | 2313 | if (optlen > sizeof(struct sctp_event_subscribe)) |
@@ -2319,14 +2320,17 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2319 | sctp_ulpevent_type_set(&sp->subscribe, SCTP_SN_TYPE_BASE + i, | 2320 | sctp_ulpevent_type_set(&sp->subscribe, SCTP_SN_TYPE_BASE + i, |
2320 | sn_type[i]); | 2321 | sn_type[i]); |
2321 | 2322 | ||
2323 | list_for_each_entry(asoc, &sp->ep->asocs, asocs) | ||
2324 | asoc->subscribe = sctp_sk(sk)->subscribe; | ||
2325 | |||
2322 | /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | 2326 | /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, |
2323 | * if there is no data to be sent or retransmit, the stack will | 2327 | * if there is no data to be sent or retransmit, the stack will |
2324 | * immediately send up this notification. | 2328 | * immediately send up this notification. |
2325 | */ | 2329 | */ |
2326 | if (sctp_ulpevent_type_enabled(sp->subscribe, SCTP_SENDER_DRY_EVENT)) { | 2330 | if (sctp_ulpevent_type_enabled(sp->subscribe, SCTP_SENDER_DRY_EVENT)) { |
2327 | struct sctp_association *asoc = sctp_id2assoc(sk, 0); | ||
2328 | struct sctp_ulpevent *event; | 2331 | struct sctp_ulpevent *event; |
2329 | 2332 | ||
2333 | asoc = sctp_id2assoc(sk, 0); | ||
2330 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | 2334 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { |
2331 | event = sctp_ulpevent_make_sender_dry_event(asoc, | 2335 | event = sctp_ulpevent_make_sender_dry_event(asoc, |
2332 | GFP_USER | __GFP_NOWARN); | 2336 | GFP_USER | __GFP_NOWARN); |
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c index ceef5a3a5aac..a6bf21579466 100644 --- a/net/sctp/stream_interleave.c +++ b/net/sctp/stream_interleave.c | |||
@@ -503,7 +503,7 @@ static int sctp_enqueue_event(struct sctp_ulpq *ulpq, | |||
503 | sk_incoming_cpu_update(sk); | 503 | sk_incoming_cpu_update(sk); |
504 | } | 504 | } |
505 | 505 | ||
506 | if (!sctp_ulpevent_is_enabled(event, sp->subscribe)) | 506 | if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe)) |
507 | goto out_free; | 507 | goto out_free; |
508 | 508 | ||
509 | if (skb_list) | 509 | if (skb_list) |
@@ -992,16 +992,17 @@ static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid, | |||
992 | __u32 mid, __u16 flags, gfp_t gfp) | 992 | __u32 mid, __u16 flags, gfp_t gfp) |
993 | { | 993 | { |
994 | struct sock *sk = ulpq->asoc->base.sk; | 994 | struct sock *sk = ulpq->asoc->base.sk; |
995 | struct sctp_sock *sp = sctp_sk(sk); | ||
996 | struct sctp_ulpevent *ev = NULL; | 995 | struct sctp_ulpevent *ev = NULL; |
997 | 996 | ||
998 | if (!sctp_ulpevent_type_enabled(sp->subscribe, | 997 | if (!sctp_ulpevent_type_enabled(ulpq->asoc->subscribe, |
999 | SCTP_PARTIAL_DELIVERY_EVENT)) | 998 | SCTP_PARTIAL_DELIVERY_EVENT)) |
1000 | return; | 999 | return; |
1001 | 1000 | ||
1002 | ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED, | 1001 | ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED, |
1003 | sid, mid, flags, gfp); | 1002 | sid, mid, flags, gfp); |
1004 | if (ev) { | 1003 | if (ev) { |
1004 | struct sctp_sock *sp = sctp_sk(sk); | ||
1005 | |||
1005 | __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev)); | 1006 | __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev)); |
1006 | 1007 | ||
1007 | if (!sp->data_ready_signalled) { | 1008 | if (!sp->data_ready_signalled) { |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index b36dd9024da3..5dde92101743 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -219,7 +219,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) | |||
219 | sk_incoming_cpu_update(sk); | 219 | sk_incoming_cpu_update(sk); |
220 | } | 220 | } |
221 | /* Check if the user wishes to receive this event. */ | 221 | /* Check if the user wishes to receive this event. */ |
222 | if (!sctp_ulpevent_is_enabled(event, sp->subscribe)) | 222 | if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe)) |
223 | goto out_free; | 223 | goto out_free; |
224 | 224 | ||
225 | /* If we are in partial delivery mode, post to the lobby until | 225 | /* If we are in partial delivery mode, post to the lobby until |
@@ -1137,7 +1137,7 @@ void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp) | |||
1137 | 1137 | ||
1138 | sk = ulpq->asoc->base.sk; | 1138 | sk = ulpq->asoc->base.sk; |
1139 | sp = sctp_sk(sk); | 1139 | sp = sctp_sk(sk); |
1140 | if (sctp_ulpevent_type_enabled(sp->subscribe, | 1140 | if (sctp_ulpevent_type_enabled(ulpq->asoc->subscribe, |
1141 | SCTP_PARTIAL_DELIVERY_EVENT)) | 1141 | SCTP_PARTIAL_DELIVERY_EVENT)) |
1142 | ev = sctp_ulpevent_make_pdapi(ulpq->asoc, | 1142 | ev = sctp_ulpevent_make_pdapi(ulpq->asoc, |
1143 | SCTP_PARTIAL_DELIVERY_ABORTED, | 1143 | SCTP_PARTIAL_DELIVERY_ABORTED, |