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 void sctp_ulpevent_nofity_peer_addr_change(struct sctp_transport *transport, 84 int state, int error); 85 86 struct sctp_ulpevent *sctp_ulpevent_make_remote_error( 87 const struct sctp_association *asoc, 88 struct sctp_chunk *chunk, 89 __u16 flags, 90 gfp_t gfp); 91 struct sctp_ulpevent *sctp_ulpevent_make_send_failed( 92 const struct sctp_association *asoc, 93 struct sctp_chunk *chunk, 94 __u16 flags, 95 __u32 error, 96 gfp_t gfp); 97 98 struct 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 105 struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( 106 const struct sctp_association *asoc, 107 __u16 flags, 108 gfp_t gfp); 109 110 struct sctp_ulpevent *sctp_ulpevent_make_pdapi( 111 const struct sctp_association *asoc, 112 __u32 indication, __u32 sid, __u32 seq, 113 __u32 flags, gfp_t gfp); 114 115 struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication( 116 const struct sctp_association *asoc, gfp_t gfp); 117 118 struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, 119 struct sctp_chunk *chunk, 120 gfp_t gfp); 121 122 struct sctp_ulpevent *sctp_ulpevent_make_authkey( 123 const struct sctp_association *asoc, __u16 key_id, 124 __u32 indication, gfp_t gfp); 125 126 struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( 127 const struct sctp_association *asoc, gfp_t gfp); 128 129 struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event( 130 const struct sctp_association *asoc, __u16 flags, 131 __u16 stream_num, __be16 *stream_list, gfp_t gfp); 132 133 struct 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 137 struct 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 141 struct 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 145 void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, 146 struct msghdr *); 147 void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event, 148 struct msghdr *); 149 void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event, 150 struct msghdr *, struct sock *sk); 151 152 __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); 153 154 static inline void sctp_ulpevent_type_set(__u16 *subscribe, 155 __u16 sn_type, __u8 on) 156 { 157 if (sn_type > SCTP_SN_TYPE_MAX) 158 return; 159 160 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? */ 167 static 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)); 173 } 174 175 /* Given an event subscription, is this event enabled? */ 176 static inline bool sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event, 177 __u16 subscribe) 178 { 179 __u16 sn_type; 180 181 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); 187 } 188 189 #endif /* __sctp_ulpevent_h__ */ 190