blob: 994e984eef324c3fb288ff622014b6ad3988ccaf [file] [log] [blame]
Thomas Gleixner47505b82019-05-23 11:14:41 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Vlad Yasevich60c778b2008-01-11 09:57:09 -05002/* SCTP kernel implementation
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * (C) Copyright IBM Corp. 2001, 2004
4 * Copyright (c) 1999-2000 Cisco, Inc.
5 * Copyright (c) 1999-2001 Motorola, Inc.
6 * Copyright (c) 2001 Intel Corp.
7 * Copyright (c) 2001 Nokia, Inc.
8 * Copyright (c) 2001 La Monte H.P. Yarroll
9 *
10 * These are the definitions needed for the sctp_ulpevent type. The
11 * sctp_ulpevent type is used to carry information from the state machine
12 * upwards to the ULP.
13 *
Vlad Yasevich60c778b2008-01-11 09:57:09 -050014 * This file is part of the SCTP kernel implementation
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 * Please send any bug reports or fixes you make to the
17 * email address(es):
Daniel Borkmann91705c62013-07-23 14:51:47 +020018 * lksctp developers <linux-sctp@vger.kernel.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 * Written or modified by:
21 * Jon Grimm <jgrimm@us.ibm.com>
22 * La Monte H.P. Yarroll <piggy@acm.org>
23 * Karl Knutson <karl@athena.chicago.il.us>
24 * Sridhar Samudrala <sri@us.ibm.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 */
26
27#ifndef __sctp_ulpevent_h__
28#define __sctp_ulpevent_h__
29
30/* A structure to carry information to the ULP (e.g. Sockets API) */
31/* Warning: This sits inside an skb.cb[] area. Be very careful of
32 * growing this structure as it is at the maximum limit now.
Xin Longbd4d6272017-12-08 21:04:04 +080033 *
34 * sctp_ulpevent is saved in sk->cb(48 bytes), whose last 4 bytes
35 * have been taken by sock_skb_cb, So here it has to use 'packed'
36 * to make sctp_ulpevent fit into the rest 44 bytes.
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 */
38struct sctp_ulpevent {
39 struct sctp_association *asoc;
Marcelo Ricardo Leitner1f45f782016-07-13 15:08:57 -030040 struct sctp_chunk *chunk;
Marcelo Ricardo Leitnerf5d258e2016-07-13 15:08:56 -030041 unsigned int rmem_len;
Xin Longbd4d6272017-12-08 21:04:04 +080042 union {
43 __u32 mid;
44 __u16 ssn;
45 };
46 union {
47 __u32 ppid;
48 __u32 fsn;
49 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 __u32 tsn;
51 __u32 cumtsn;
Marcelo Ricardo Leitnerf5d258e2016-07-13 15:08:56 -030052 __u16 stream;
Marcelo Ricardo Leitnerf5d258e2016-07-13 15:08:56 -030053 __u16 flags;
54 __u16 msg_flags;
Xin Longbd4d6272017-12-08 21:04:04 +080055} __packed;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
57/* Retrieve the skb this event sits inside of. */
Vlad Yasevichab38fb02008-04-12 18:40:06 -070058static inline struct sk_buff *sctp_event2skb(const struct sctp_ulpevent *ev)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059{
60 return container_of((void *)ev, struct sk_buff, cb);
61}
62
63/* Retrieve & cast the event sitting inside the skb. */
64static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb)
65{
66 return (struct sctp_ulpevent *)skb->cb;
67}
68
69void sctp_ulpevent_free(struct sctp_ulpevent *);
70int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
Thomas Grafcd4fcc72011-07-08 04:37:46 +000071unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
74 const struct sctp_association *asoc,
75 __u16 flags,
76 __u16 state,
77 __u16 error,
78 __u16 outbound,
79 __u16 inbound,
Vlad Yasevicha5a35e72007-03-23 11:34:08 -070080 struct sctp_chunk *chunk,
Al Virodd0fc662005-10-07 07:46:04 +010081 gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
Jonas Falkevik50ce4c02020-05-27 11:59:43 +020083void sctp_ulpevent_notify_peer_addr_change(struct sctp_transport *transport,
Xin Long4b774032019-10-08 19:27:33 +080084 int state, int error);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
87 const struct sctp_association *asoc,
88 struct sctp_chunk *chunk,
89 __u16 flags,
Al Virodd0fc662005-10-07 07:46:04 +010090 gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
92 const struct sctp_association *asoc,
93 struct sctp_chunk *chunk,
94 __u16 flags,
95 __u32 error,
Al Virodd0fc662005-10-07 07:46:04 +010096 gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Xin Longb6e6b5f2019-10-08 19:27:36 +080098struct sctp_ulpevent *sctp_ulpevent_make_send_failed_event(
99 const struct sctp_association *asoc,
100 struct sctp_chunk *chunk,
101 __u16 flags,
102 __u32 error,
103 gfp_t gfp);
104
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
106 const struct sctp_association *asoc,
107 __u16 flags,
Al Virodd0fc662005-10-07 07:46:04 +0100108 gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
111 const struct sctp_association *asoc,
Xin Long65f5e352017-12-08 21:04:08 +0800112 __u32 indication, __u32 sid, __u32 seq,
113 __u32 flags, gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Ivan Skytte Jorgensen0f3fffd2006-12-20 16:07:04 -0800115struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
Al Virodd0fc662005-10-07 07:46:04 +0100116 const struct sctp_association *asoc, gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
118struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
119 struct sctp_chunk *chunk,
Al Virodd0fc662005-10-07 07:46:04 +0100120 gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Vlad Yasevich65b07e52007-09-16 19:34:00 -0700122struct sctp_ulpevent *sctp_ulpevent_make_authkey(
123 const struct sctp_association *asoc, __u16 key_id,
124 __u32 indication, gfp_t gfp);
125
Wei Yongjune1cdd552011-04-17 17:29:03 +0000126struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
127 const struct sctp_association *asoc, gfp_t gfp);
128
Xin Long35ea82d2017-02-17 12:45:38 +0800129struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event(
130 const struct sctp_association *asoc, __u16 flags,
Xin Long1da4fc92017-10-28 19:43:54 +0800131 __u16 stream_num, __be16 *stream_list, gfp_t gfp);
Xin Long35ea82d2017-02-17 12:45:38 +0800132
Xin Longc95129d2017-03-10 12:11:06 +0800133struct sctp_ulpevent *sctp_ulpevent_make_assoc_reset_event(
134 const struct sctp_association *asoc, __u16 flags,
135 __u32 local_tsn, __u32 remote_tsn, gfp_t gfp);
136
Xin Longb4441532017-03-10 12:11:08 +0800137struct sctp_ulpevent *sctp_ulpevent_make_stream_change_event(
138 const struct sctp_association *asoc, __u16 flags,
139 __u32 strchange_instrms, __u32 strchange_outstrms, gfp_t gfp);
140
Xin Longbd4d6272017-12-08 21:04:04 +0800141struct sctp_ulpevent *sctp_make_reassembled_event(
142 struct net *net, struct sk_buff_head *queue,
143 struct sk_buff *f_frag, struct sk_buff *l_frag);
144
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
Geir Ola Vaagland0d3a4212014-07-12 20:30:37 +0200146 struct msghdr *);
147void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
148 struct msghdr *);
Geir Ola Vaagland2347c802014-07-12 20:30:38 +0200149void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
150 struct msghdr *, struct sock *sk);
Geir Ola Vaagland0d3a4212014-07-12 20:30:37 +0200151
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
153
Xin Long2cc0eeb2018-11-18 16:08:51 +0800154static inline void sctp_ulpevent_type_set(__u16 *subscribe,
155 __u16 sn_type, __u8 on)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156{
Xin Long2cc0eeb2018-11-18 16:08:51 +0800157 if (sn_type > SCTP_SN_TYPE_MAX)
158 return;
Dan Carpenterfa5f7b52017-09-14 02:00:54 +0300159
Xin Long2cc0eeb2018-11-18 16:08:51 +0800160 if (on)
161 *subscribe |= (1 << (sn_type - SCTP_SN_TYPE_BASE));
162 else
163 *subscribe &= ~(1 << (sn_type - SCTP_SN_TYPE_BASE));
164}
165
166/* Is this event type enabled? */
167static inline bool sctp_ulpevent_type_enabled(__u16 subscribe, __u16 sn_type)
168{
169 if (sn_type > SCTP_SN_TYPE_MAX)
170 return false;
171
172 return subscribe & (1 << (sn_type - SCTP_SN_TYPE_BASE));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173}
174
175/* Given an event subscription, is this event enabled? */
Xin Long2cc0eeb2018-11-18 16:08:51 +0800176static inline bool sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
177 __u16 subscribe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178{
179 __u16 sn_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180
Xin Long2cc0eeb2018-11-18 16:08:51 +0800181 if (!sctp_ulpevent_is_notification(event))
182 return true;
183
184 sn_type = sctp_ulpevent_get_notification_type(event);
185
186 return sctp_ulpevent_type_enabled(subscribe, sn_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187}
188
189#endif /* __sctp_ulpevent_h__ */