1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* SCTP kernel implementation 3 * (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 * 14 * This file is part of the SCTP kernel implementation 15 * 16 * Please send any bug reports or fixes you make to the 17 * email address(es): 18 * lksctp developers <linux-sctp@vger.kernel.org> 19 * 20 * 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> 25 */ 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. 33 * 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. 37 */ 38 struct sctp_ulpevent { 39 struct sctp_association *asoc; 40 struct sctp_chunk *chunk; 41 unsigned int rmem_len; 42 union { 43 __u32 mid; 44 __u16 ssn; 45 }; 46 union { 47 __u32 ppid; 48 __u32 fsn; 49 }; 50 __u32 tsn; 51 __u32 cumtsn; 52 __u16 stream; 53 __u16 flags; 54 __u16 msg_flags; 55 } __packed; 56 57 /* Retrieve the skb this event sits inside of. */ 58 static inline struct sk_buff *sctp_event2skb(const struct sctp_ulpevent *ev) 59 { 60 return container_of((void *)ev, struct sk_buff, cb); 61 } 62 63 /* Retrieve & cast the event sitting inside the skb. */ 64 static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb) 65 { 66 return (struct sctp_ulpevent *)skb->cb; 67 } 68 69 void sctp_ulpevent_free(struct sctp_ulpevent *); 70 int sctp_ulpevent_is_notification(const struct sctp_ulpevent *); 71 unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list); 72 73 struct 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, 80 struct sctp_chunk *chunk, 81 gfp_t gfp); 82 83 struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( 84 const struct sctp_association *asoc, 85 const struct sockaddr_storage *aaddr, 86 int flags, 87 int state, 88 int error, 89 gfp_t gfp); 90 91 struct sctp_ulpevent *sctp_ulpevent_make_remote_error( 92 const struct sctp_association *asoc, 93 struct sctp_chunk *chunk, 94 __u16 flags, 95 gfp_t gfp); 96 struct sctp_ulpevent *sctp_ulpevent_make_send_failed( 97 const struct sctp_association *asoc, 98 struct sctp_chunk *chunk, 99 __u16 flags, 100 __u32 error, 101 gfp_t gfp); 102 103 struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( 104 const struct sctp_association *asoc, 105 __u16 flags, 106 gfp_t gfp); 107 108 struct sctp_ulpevent *sctp_ulpevent_make_pdapi( 109 const struct sctp_association *asoc, 110 __u32 indication, __u32 sid, __u32 seq, 111 __u32 flags, gfp_t gfp); 112 113 struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication( 114 const struct sctp_association *asoc, gfp_t gfp); 115 116 struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, 117 struct sctp_chunk *chunk, 118 gfp_t gfp); 119 120 struct sctp_ulpevent *sctp_ulpevent_make_authkey( 121 const struct sctp_association *asoc, __u16 key_id, 122 __u32 indication, gfp_t gfp); 123 124 struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( 125 const struct sctp_association *asoc, gfp_t gfp); 126 127 struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event( 128 const struct sctp_association *asoc, __u16 flags, 129 __u16 stream_num, __be16 *stream_list, gfp_t gfp); 130 131 struct sctp_ulpevent *sctp_ulpevent_make_assoc_reset_event( 132 const struct sctp_association *asoc, __u16 flags, 133 __u32 local_tsn, __u32 remote_tsn, gfp_t gfp); 134 135 struct sctp_ulpevent *sctp_ulpevent_make_stream_change_event( 136 const struct sctp_association *asoc, __u16 flags, 137 __u32 strchange_instrms, __u32 strchange_outstrms, gfp_t gfp); 138 139 struct sctp_ulpevent *sctp_make_reassembled_event( 140 struct net *net, struct sk_buff_head *queue, 141 struct sk_buff *f_frag, struct sk_buff *l_frag); 142 143 void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, 144 struct msghdr *); 145 void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event, 146 struct msghdr *); 147 void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event, 148 struct msghdr *, struct sock *sk); 149 150 __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); 151 152 static inline void sctp_ulpevent_type_set(__u16 *subscribe, 153 __u16 sn_type, __u8 on) 154 { 155 if (sn_type > SCTP_SN_TYPE_MAX) 156 return; 157 158 if (on) 159 *subscribe |= (1 << (sn_type - SCTP_SN_TYPE_BASE)); 160 else 161 *subscribe &= ~(1 << (sn_type - SCTP_SN_TYPE_BASE)); 162 } 163 164 /* Is this event type enabled? */ 165 static inline bool sctp_ulpevent_type_enabled(__u16 subscribe, __u16 sn_type) 166 { 167 if (sn_type > SCTP_SN_TYPE_MAX) 168 return false; 169 170 return subscribe & (1 << (sn_type - SCTP_SN_TYPE_BASE)); 171 } 172 173 /* Given an event subscription, is this event enabled? */ 174 static inline bool sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event, 175 __u16 subscribe) 176 { 177 __u16 sn_type; 178 179 if (!sctp_ulpevent_is_notification(event)) 180 return true; 181 182 sn_type = sctp_ulpevent_get_notification_type(event); 183 184 return sctp_ulpevent_type_enabled(subscribe, sn_type); 185 } 186 187 #endif /* __sctp_ulpevent_h__ */ 188