ulpevent.h (5606B)
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 */ 38struct 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. */ 58static 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. */ 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 *); 71unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list); 72 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, 80 struct sctp_chunk *chunk, 81 gfp_t gfp); 82 83void sctp_ulpevent_notify_peer_addr_change(struct sctp_transport *transport, 84 int state, int error); 85 86struct 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); 91struct 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 98struct 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 105struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( 106 const struct sctp_association *asoc, 107 __u16 flags, 108 gfp_t gfp); 109 110struct 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 115struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication( 116 const struct sctp_association *asoc, gfp_t gfp); 117 118struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, 119 struct sctp_chunk *chunk, 120 gfp_t gfp); 121 122struct sctp_ulpevent *sctp_ulpevent_make_authkey( 123 const struct sctp_association *asoc, __u16 key_id, 124 __u32 indication, gfp_t gfp); 125 126struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( 127 const struct sctp_association *asoc, gfp_t gfp); 128 129struct 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 133struct 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 137struct 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 141struct 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 145void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, 146 struct msghdr *); 147void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event, 148 struct msghdr *); 149void 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 154static 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? */ 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)); 173} 174 175/* Given an event subscription, is this event enabled? */ 176static 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__ */