147505b8bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 260c778b2SVlad Yasevich /* SCTP kernel implementation 31da177e4SLinus Torvalds * (C) Copyright IBM Corp. 2001, 2004 41da177e4SLinus Torvalds * Copyright (c) 1999-2000 Cisco, Inc. 51da177e4SLinus Torvalds * Copyright (c) 1999-2001 Motorola, Inc. 61da177e4SLinus Torvalds * Copyright (c) 2001-2003 Intel Corp. 71da177e4SLinus Torvalds * 860c778b2SVlad Yasevich * This file is part of the SCTP kernel implementation 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * The base lksctp header. 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 131da177e4SLinus Torvalds * email address(es): 1491705c61SDaniel Borkmann * lksctp developers <linux-sctp@vger.kernel.org> 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * Written or modified by: 171da177e4SLinus Torvalds * La Monte H.P. Yarroll <piggy@acm.org> 181da177e4SLinus Torvalds * Xingang Guo <xingang.guo@intel.com> 191da177e4SLinus Torvalds * Jon Grimm <jgrimm@us.ibm.com> 201da177e4SLinus Torvalds * Daisy Chang <daisyc@us.ibm.com> 211da177e4SLinus Torvalds * Sridhar Samudrala <sri@us.ibm.com> 221da177e4SLinus Torvalds * Ardelle Fan <ardelle.fan@intel.com> 231da177e4SLinus Torvalds * Ryan Layer <rmlayer@us.ibm.com> 241da177e4SLinus Torvalds * Kevin Gao <kevin.gao@intel.com> 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #ifndef __net_sctp_h__ 281da177e4SLinus Torvalds #define __net_sctp_h__ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds /* Header Strategy. 311da177e4SLinus Torvalds * Start getting some control over the header file depencies: 321da177e4SLinus Torvalds * includes 331da177e4SLinus Torvalds * constants 341da177e4SLinus Torvalds * structs 351da177e4SLinus Torvalds * prototypes 361da177e4SLinus Torvalds * macros, externs, and inlines 371da177e4SLinus Torvalds * 381da177e4SLinus Torvalds * Move test_frame specific items out of the kernel headers 391da177e4SLinus Torvalds * and into the test frame headers. This is not perfect in any sense 401da177e4SLinus Torvalds * and will continue to evolve. 411da177e4SLinus Torvalds */ 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds #include <linux/types.h> 441da177e4SLinus Torvalds #include <linux/slab.h> 451da177e4SLinus Torvalds #include <linux/in.h> 461da177e4SLinus Torvalds #include <linux/tty.h> 471da177e4SLinus Torvalds #include <linux/proc_fs.h> 481da177e4SLinus Torvalds #include <linux/spinlock.h> 491da177e4SLinus Torvalds #include <linux/jiffies.h> 501da177e4SLinus Torvalds #include <linux/idr.h> 511da177e4SLinus Torvalds 52dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 531da177e4SLinus Torvalds #include <net/ipv6.h> 541da177e4SLinus Torvalds #include <net/ip6_route.h> 551da177e4SLinus Torvalds #endif 561da177e4SLinus Torvalds 577c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 581da177e4SLinus Torvalds #include <asm/page.h> 591da177e4SLinus Torvalds #include <net/sock.h> 601da177e4SLinus Torvalds #include <net/snmp.h> 611da177e4SLinus Torvalds #include <net/sctp/structs.h> 621da177e4SLinus Torvalds #include <net/sctp/constants.h> 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds #ifdef CONFIG_IP_SCTP_MODULE 651da177e4SLinus Torvalds #define SCTP_PROTOSW_FLAG 0 661da177e4SLinus Torvalds #else /* static! */ 671da177e4SLinus Torvalds #define SCTP_PROTOSW_FLAG INET_PROTOSW_PERMANENT 681da177e4SLinus Torvalds #endif 691da177e4SLinus Torvalds 703822a5ffSMarcelo Ricardo Leitner /* Round an int up to the next multiple of 4. */ 71e2f036a9SMarcelo Ricardo Leitner #define SCTP_PAD4(s) (((s)+3)&~3) 723822a5ffSMarcelo Ricardo Leitner /* Truncate to the previous multiple of 4. */ 73e2f036a9SMarcelo Ricardo Leitner #define SCTP_TRUNC4(s) ((s)&~3) 743822a5ffSMarcelo Ricardo Leitner 751da177e4SLinus Torvalds /* 761da177e4SLinus Torvalds * Function declarations. 771da177e4SLinus Torvalds */ 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds /* 801da177e4SLinus Torvalds * sctp/protocol.c 811da177e4SLinus Torvalds */ 821c662018SXin Long int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *addr, 831c662018SXin Long enum sctp_scope, gfp_t gfp, int flags); 847b584460SJoe Perches struct sctp_pf *sctp_get_pf_specific(sa_family_t family); 857b584460SJoe Perches int sctp_register_pf(struct sctp_pf *, sa_family_t); 867b584460SJoe Perches void sctp_addr_wq_mgmt(struct net *, struct sctp_sockaddr_entry *, int); 87965ae444SXin Long int sctp_udp_sock_start(struct net *net); 88965ae444SXin Long void sctp_udp_sock_stop(struct net *net); 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds /* 911da177e4SLinus Torvalds * sctp/socket.c 921da177e4SLinus Torvalds */ 93644fbdeaSXin Long int sctp_inet_connect(struct socket *sock, struct sockaddr *uaddr, 94644fbdeaSXin Long int addr_len, int flags); 951da177e4SLinus Torvalds int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb); 961da177e4SLinus Torvalds int sctp_inet_listen(struct socket *sock, int backlog); 971da177e4SLinus Torvalds void sctp_write_space(struct sock *sk); 98676d2369SDavid S. Miller void sctp_data_ready(struct sock *sk); 99a11e1d43SLinus Torvalds __poll_t sctp_poll(struct file *file, struct socket *sock, 100a11e1d43SLinus Torvalds poll_table *wait); 101331c4ee7SVlad Yasevich void sctp_sock_rfree(struct sk_buff *skb); 102914e1c8bSVlad Yasevich void sctp_copy_sock(struct sock *newsk, struct sock *sk, 103914e1c8bSVlad Yasevich struct sctp_association *asoc); 1041748376bSEric Dumazet extern struct percpu_counter sctp_sockets_allocated; 1057b584460SJoe Perches int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); 1062347c80fSGeir Ola Vaagland struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *); 1071da177e4SLinus Torvalds 10897a6ec4aSTom Herbert void sctp_transport_walk_start(struct rhashtable_iter *iter); 109626d16f5SXin Long void sctp_transport_walk_stop(struct rhashtable_iter *iter); 110626d16f5SXin Long struct sctp_transport *sctp_transport_get_next(struct net *net, 111626d16f5SXin Long struct rhashtable_iter *iter); 112626d16f5SXin Long struct sctp_transport *sctp_transport_get_idx(struct net *net, 113626d16f5SXin Long struct rhashtable_iter *iter, int pos); 114626d16f5SXin Long int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), 115626d16f5SXin Long struct net *net, 116626d16f5SXin Long const union sctp_addr *laddr, 117626d16f5SXin Long const union sctp_addr *paddr, void *p); 118626d16f5SXin Long int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *), 119d25adbebSXin Long int (*cb_done)(struct sctp_transport *, void *), 120d25adbebSXin Long struct net *net, int *pos, void *p); 121626d16f5SXin Long int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p); 12252c52a61SXin Long int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, 12352c52a61SXin Long struct sctp_info *info); 12452c52a61SXin Long 1251da177e4SLinus Torvalds /* 1261da177e4SLinus Torvalds * sctp/primitive.c 1271da177e4SLinus Torvalds */ 12855e26eb9SEric W. Biederman int sctp_primitive_ASSOCIATE(struct net *, struct sctp_association *, void *arg); 12955e26eb9SEric W. Biederman int sctp_primitive_SHUTDOWN(struct net *, struct sctp_association *, void *arg); 13055e26eb9SEric W. Biederman int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg); 13155e26eb9SEric W. Biederman int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg); 13255e26eb9SEric W. Biederman int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg); 13355e26eb9SEric W. Biederman int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg); 1347a090b04SXin Long int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc, 1357a090b04SXin Long void *arg); 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds /* 1381da177e4SLinus Torvalds * sctp/input.c 1391da177e4SLinus Torvalds */ 1401da177e4SLinus Torvalds int sctp_rcv(struct sk_buff *skb); 14132bbd879SStefano Brivio int sctp_v4_err(struct sk_buff *skb, u32 info); 14276c6d988SXin Long int sctp_hash_endpoint(struct sctp_endpoint *ep); 1431da177e4SLinus Torvalds void sctp_unhash_endpoint(struct sctp_endpoint *); 1444110cc25SEric W. Biederman struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *, 145d1ad1ff2SSridhar Samudrala struct sctphdr *, struct sctp_association **, 1461da177e4SLinus Torvalds struct sctp_transport **); 147dae399d7SXin Long void sctp_err_finish(struct sock *, struct sctp_transport *); 1489e47df00SXin Long int sctp_udp_v4_err(struct sock *sk, struct sk_buff *skb); 1499e47df00SXin Long int sctp_udp_v6_err(struct sock *sk, struct sk_buff *skb); 1501da177e4SLinus Torvalds void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, 1511da177e4SLinus Torvalds struct sctp_transport *t, __u32 pmtu); 152ec18d9a2SDavid S. Miller void sctp_icmp_redirect(struct sock *, struct sctp_transport *, 153ec18d9a2SDavid S. Miller struct sk_buff *); 1541da177e4SLinus Torvalds void sctp_icmp_proto_unreachable(struct sock *sk, 1551da177e4SLinus Torvalds struct sctp_association *asoc, 1561da177e4SLinus Torvalds struct sctp_transport *t); 157c4d2444eSSridhar Samudrala void sctp_backlog_migrate(struct sctp_association *assoc, 158c4d2444eSSridhar Samudrala struct sock *oldsk, struct sock *newsk); 159d6c0256aSXin Long int sctp_transport_hashtable_init(void); 160d6c0256aSXin Long void sctp_transport_hashtable_destroy(void); 1617fda702fSXin Long int sctp_hash_transport(struct sctp_transport *t); 162d6c0256aSXin Long void sctp_unhash_transport(struct sctp_transport *t); 163d6c0256aSXin Long struct sctp_transport *sctp_addrs_lookup_transport( 164d6c0256aSXin Long struct net *net, 165d6c0256aSXin Long const union sctp_addr *laddr, 166d6c0256aSXin Long const union sctp_addr *paddr); 167d6c0256aSXin Long struct sctp_transport *sctp_epaddr_lookup_transport( 168d6c0256aSXin Long const struct sctp_endpoint *ep, 169d6c0256aSXin Long const union sctp_addr *paddr); 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds /* 17216164366SAdrian Bunk * sctp/proc.c 17316164366SAdrian Bunk */ 174d47d08c8SAl Viro int __net_init sctp_proc_init(struct net *net); 17516164366SAdrian Bunk 17690017accSMarcelo Ricardo Leitner /* 17790017accSMarcelo Ricardo Leitner * sctp/offload.c 17890017accSMarcelo Ricardo Leitner */ 17990017accSMarcelo Ricardo Leitner int sctp_offload_init(void); 18016164366SAdrian Bunk 18116164366SAdrian Bunk /* 1821ba896f6SXin Long * sctp/stream_sched.c 1831ba896f6SXin Long */ 1841ba896f6SXin Long void sctp_sched_ops_init(void); 1851ba896f6SXin Long 1861ba896f6SXin Long /* 1877f9d68acSXin Long * sctp/stream.c 1887f9d68acSXin Long */ 1897f9d68acSXin Long int sctp_send_reset_streams(struct sctp_association *asoc, 1907f9d68acSXin Long struct sctp_reset_streams *params); 191a92ce1a4SXin Long int sctp_send_reset_assoc(struct sctp_association *asoc); 192242bd2d5SXin Long int sctp_send_add_streams(struct sctp_association *asoc, 193242bd2d5SXin Long struct sctp_add_streams *params); 1947f9d68acSXin Long 1957f9d68acSXin Long /* 1960a5fcb9cSsebastian@breakpoint.cc * Module global variables 1970a5fcb9cSsebastian@breakpoint.cc */ 1980a5fcb9cSsebastian@breakpoint.cc 1990a5fcb9cSsebastian@breakpoint.cc /* 2000a5fcb9cSsebastian@breakpoint.cc * sctp/protocol.c 2010a5fcb9cSsebastian@breakpoint.cc */ 2020a5fcb9cSsebastian@breakpoint.cc extern struct kmem_cache *sctp_chunk_cachep __read_mostly; 2030a5fcb9cSsebastian@breakpoint.cc extern struct kmem_cache *sctp_bucket_cachep __read_mostly; 2047e3ea6d5SYing Xue extern long sysctl_sctp_mem[3]; 2057e3ea6d5SYing Xue extern int sysctl_sctp_rmem[3]; 2067e3ea6d5SYing Xue extern int sysctl_sctp_wmem[3]; 2070a5fcb9cSsebastian@breakpoint.cc 2080a5fcb9cSsebastian@breakpoint.cc /* 2091da177e4SLinus Torvalds * Section: Macros, externs, and inlines 2101da177e4SLinus Torvalds */ 2111da177e4SLinus Torvalds 2121da177e4SLinus Torvalds /* SCTP SNMP MIB stats handlers */ 213b01a2407SEric W. Biederman #define SCTP_INC_STATS(net, field) SNMP_INC_STATS((net)->sctp.sctp_statistics, field) 21413415e46SEric Dumazet #define __SCTP_INC_STATS(net, field) __SNMP_INC_STATS((net)->sctp.sctp_statistics, field) 215b01a2407SEric W. Biederman #define SCTP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->sctp.sctp_statistics, field) 2161da177e4SLinus Torvalds 217ac0b0462SSridhar Samudrala /* sctp mib definitions */ 218fd2c3ef7SEric Dumazet enum { 219ac0b0462SSridhar Samudrala SCTP_MIB_NUM = 0, 220ac0b0462SSridhar Samudrala SCTP_MIB_CURRESTAB, /* CurrEstab */ 221ac0b0462SSridhar Samudrala SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */ 222ac0b0462SSridhar Samudrala SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */ 223ac0b0462SSridhar Samudrala SCTP_MIB_ABORTEDS, /* Aborteds */ 224ac0b0462SSridhar Samudrala SCTP_MIB_SHUTDOWNS, /* Shutdowns */ 225ac0b0462SSridhar Samudrala SCTP_MIB_OUTOFBLUES, /* OutOfBlues */ 226ac0b0462SSridhar Samudrala SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */ 227ac0b0462SSridhar Samudrala SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */ 228ac0b0462SSridhar Samudrala SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */ 229ac0b0462SSridhar Samudrala SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */ 230ac0b0462SSridhar Samudrala SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */ 231ac0b0462SSridhar Samudrala SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */ 232ac0b0462SSridhar Samudrala SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */ 233ac0b0462SSridhar Samudrala SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */ 234ac0b0462SSridhar Samudrala SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */ 235ac0b0462SSridhar Samudrala SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */ 236ac0b0462SSridhar Samudrala SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */ 237ac0b0462SSridhar Samudrala SCTP_MIB_T1_INIT_EXPIREDS, 238ac0b0462SSridhar Samudrala SCTP_MIB_T1_COOKIE_EXPIREDS, 239ac0b0462SSridhar Samudrala SCTP_MIB_T2_SHUTDOWN_EXPIREDS, 240ac0b0462SSridhar Samudrala SCTP_MIB_T3_RTX_EXPIREDS, 241ac0b0462SSridhar Samudrala SCTP_MIB_T4_RTO_EXPIREDS, 242ac0b0462SSridhar Samudrala SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS, 243ac0b0462SSridhar Samudrala SCTP_MIB_DELAY_SACK_EXPIREDS, 244ac0b0462SSridhar Samudrala SCTP_MIB_AUTOCLOSE_EXPIREDS, 245b6157d8eSVlad Yasevich SCTP_MIB_T1_RETRANSMITS, 246ac0b0462SSridhar Samudrala SCTP_MIB_T3_RETRANSMITS, 247ac0b0462SSridhar Samudrala SCTP_MIB_PMTUD_RETRANSMITS, 248ac0b0462SSridhar Samudrala SCTP_MIB_FAST_RETRANSMITS, 249ac0b0462SSridhar Samudrala SCTP_MIB_IN_PKT_SOFTIRQ, 250ac0b0462SSridhar Samudrala SCTP_MIB_IN_PKT_BACKLOG, 251ac0b0462SSridhar Samudrala SCTP_MIB_IN_PKT_DISCARDS, 252ac0b0462SSridhar Samudrala SCTP_MIB_IN_DATA_CHUNK_DISCARDS, 253ac0b0462SSridhar Samudrala __SCTP_MIB_MAX 254ac0b0462SSridhar Samudrala }; 255ac0b0462SSridhar Samudrala 256ac0b0462SSridhar Samudrala #define SCTP_MIB_MAX __SCTP_MIB_MAX 257ac0b0462SSridhar Samudrala struct sctp_mib { 258ac0b0462SSridhar Samudrala unsigned long mibs[SCTP_MIB_MAX]; 259ec733b15SEric Dumazet }; 260ac0b0462SSridhar Samudrala 261196d6759SMichele Baldessari /* helper function to track stats about max rto and related transport */ 262196d6759SMichele Baldessari static inline void sctp_max_rto(struct sctp_association *asoc, 263196d6759SMichele Baldessari struct sctp_transport *trans) 264196d6759SMichele Baldessari { 265196d6759SMichele Baldessari if (asoc->stats.max_obs_rto < (__u64)trans->rto) { 266196d6759SMichele Baldessari asoc->stats.max_obs_rto = trans->rto; 267196d6759SMichele Baldessari memset(&asoc->stats.obs_rto_ipaddr, 0, 268196d6759SMichele Baldessari sizeof(struct sockaddr_storage)); 269196d6759SMichele Baldessari memcpy(&asoc->stats.obs_rto_ipaddr, &trans->ipaddr, 270196d6759SMichele Baldessari trans->af_specific->sockaddr_len); 271196d6759SMichele Baldessari } 272196d6759SMichele Baldessari } 2731da177e4SLinus Torvalds 2741da177e4SLinus Torvalds /* 2751da177e4SLinus Torvalds * Macros for keeping a global reference of object allocations. 2761da177e4SLinus Torvalds */ 2771da177e4SLinus Torvalds #ifdef CONFIG_SCTP_DBG_OBJCNT 2781da177e4SLinus Torvalds 2791da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_sock; 2801da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_ep; 2811da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_assoc; 2821da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_transport; 2831da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_chunk; 2841da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_bind_addr; 2851da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_bind_bucket; 2861da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_addr; 2871da177e4SLinus Torvalds extern atomic_t sctp_dbg_objcnt_datamsg; 2881f485649SVlad Yasevich extern atomic_t sctp_dbg_objcnt_keys; 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds /* Macros to atomically increment/decrement objcnt counters. */ 2911da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT_INC(name) \ 2921da177e4SLinus Torvalds atomic_inc(&sctp_dbg_objcnt_## name) 2931da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT_DEC(name) \ 2941da177e4SLinus Torvalds atomic_dec(&sctp_dbg_objcnt_## name) 2951da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT(name) \ 2961da177e4SLinus Torvalds atomic_t sctp_dbg_objcnt_## name = ATOMIC_INIT(0) 2971da177e4SLinus Torvalds 298d86f9868SRandy Dunlap /* Macro to help create new entries in the global array of 2991da177e4SLinus Torvalds * objcnt counters. 3001da177e4SLinus Torvalds */ 3011da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT_ENTRY(name) \ 3021da177e4SLinus Torvalds {.label= #name, .counter= &sctp_dbg_objcnt_## name} 3031da177e4SLinus Torvalds 30413d782f6SEric W. Biederman void sctp_dbg_objcnt_init(struct net *); 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds #else 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT_INC(name) 3091da177e4SLinus Torvalds #define SCTP_DBG_OBJCNT_DEC(name) 3101da177e4SLinus Torvalds 3111f07b62fSCong Wang static inline void sctp_dbg_objcnt_init(struct net *net) { return; } 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds #endif /* CONFIG_SCTP_DBG_OBJCOUNT */ 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds #if defined CONFIG_SYSCTL 3161da177e4SLinus Torvalds void sctp_sysctl_register(void); 3171da177e4SLinus Torvalds void sctp_sysctl_unregister(void); 318ebb7e95dSEric W. Biederman int sctp_sysctl_net_register(struct net *net); 319ebb7e95dSEric W. Biederman void sctp_sysctl_net_unregister(struct net *net); 3201da177e4SLinus Torvalds #else 3211da177e4SLinus Torvalds static inline void sctp_sysctl_register(void) { return; } 3221da177e4SLinus Torvalds static inline void sctp_sysctl_unregister(void) { return; } 323ebb7e95dSEric W. Biederman static inline int sctp_sysctl_net_register(struct net *net) { return 0; } 324ebb7e95dSEric W. Biederman static inline void sctp_sysctl_net_unregister(struct net *net) { return; } 3251da177e4SLinus Torvalds #endif 3261da177e4SLinus Torvalds 3271da177e4SLinus Torvalds /* Size of Supported Address Parameter for 'x' address types. */ 3281da177e4SLinus Torvalds #define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16)) 3291da177e4SLinus Torvalds 330dfd56b8bSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 3311da177e4SLinus Torvalds 332270637abSVlad Yasevich void sctp_v6_pf_init(void); 333270637abSVlad Yasevich void sctp_v6_pf_exit(void); 334270637abSVlad Yasevich int sctp_v6_protosw_init(void); 335270637abSVlad Yasevich void sctp_v6_protosw_exit(void); 336827bf122SSridhar Samudrala int sctp_v6_add_protocol(void); 337827bf122SSridhar Samudrala void sctp_v6_del_protocol(void); 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds #else /* #ifdef defined(CONFIG_IPV6) */ 3401da177e4SLinus Torvalds 3411233823bSDavid S. Miller static inline void sctp_v6_pf_init(void) { return; } 342270637abSVlad Yasevich static inline void sctp_v6_pf_exit(void) { return; } 343270637abSVlad Yasevich static inline int sctp_v6_protosw_init(void) { return 0; } 344270637abSVlad Yasevich static inline void sctp_v6_protosw_exit(void) { return; } 345827bf122SSridhar Samudrala static inline int sctp_v6_add_protocol(void) { return 0; } 346827bf122SSridhar Samudrala static inline void sctp_v6_del_protocol(void) { return; } 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds #endif /* #if defined(CONFIG_IPV6) */ 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvalds /* Map an association to an assoc_id. */ 3521da177e4SLinus Torvalds static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) 3531da177e4SLinus Torvalds { 354a02cec21SEric Dumazet return asoc ? asoc->assoc_id : 0; 3551da177e4SLinus Torvalds } 3561da177e4SLinus Torvalds 35738ab1fa9SDaniel Borkmann static inline enum sctp_sstat_state 35838ab1fa9SDaniel Borkmann sctp_assoc_to_state(const struct sctp_association *asoc) 35938ab1fa9SDaniel Borkmann { 36038ab1fa9SDaniel Borkmann /* SCTP's uapi always had SCTP_EMPTY(=0) as a dummy state, but we 36138ab1fa9SDaniel Borkmann * got rid of it in kernel space. Therefore SCTP_CLOSED et al 36238ab1fa9SDaniel Borkmann * start at =1 in user space, but actually as =0 in kernel space. 36338ab1fa9SDaniel Borkmann * Now that we can not break user space and SCTP_EMPTY is exposed 36438ab1fa9SDaniel Borkmann * there, we need to fix it up with an ugly offset not to break 36538ab1fa9SDaniel Borkmann * applications. :( 36638ab1fa9SDaniel Borkmann */ 36738ab1fa9SDaniel Borkmann return asoc->state + 1; 36838ab1fa9SDaniel Borkmann } 36938ab1fa9SDaniel Borkmann 3701da177e4SLinus Torvalds /* Look up the association by its id. */ 3711da177e4SLinus Torvalds struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id); 3721da177e4SLinus Torvalds 3730343c554SBenjamin Poirier int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp); 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds /* A macro to walk a list of skbs. */ 3761da177e4SLinus Torvalds #define sctp_skb_for_each(pos, head, tmp) \ 3773d09274cSDavid S. Miller skb_queue_walk_safe(head, pos, tmp) 3781da177e4SLinus Torvalds 3791da177e4SLinus Torvalds /** 3801da177e4SLinus Torvalds * sctp_list_dequeue - remove from the head of the queue 3811da177e4SLinus Torvalds * @list: list to dequeue from 3821da177e4SLinus Torvalds * 3831da177e4SLinus Torvalds * Remove the head of the list. The head item is 3841da177e4SLinus Torvalds * returned or %NULL if the list is empty. 3851da177e4SLinus Torvalds */ 3861da177e4SLinus Torvalds 3871da177e4SLinus Torvalds static inline struct list_head *sctp_list_dequeue(struct list_head *list) 3881da177e4SLinus Torvalds { 3891da177e4SLinus Torvalds struct list_head *result = NULL; 3901da177e4SLinus Torvalds 391eb8e9771SMarcelo Ricardo Leitner if (!list_empty(list)) { 3921da177e4SLinus Torvalds result = list->next; 393eb8e9771SMarcelo Ricardo Leitner list_del_init(result); 3941da177e4SLinus Torvalds } 3951da177e4SLinus Torvalds return result; 3961da177e4SLinus Torvalds } 3971da177e4SLinus Torvalds 398331c4ee7SVlad Yasevich /* SCTP version of skb_set_owner_r. We need this one because 399331c4ee7SVlad Yasevich * of the way we have to do receive buffer accounting on bundled 400331c4ee7SVlad Yasevich * chunks. 401331c4ee7SVlad Yasevich */ 402331c4ee7SVlad Yasevich static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) 403331c4ee7SVlad Yasevich { 404331c4ee7SVlad Yasevich struct sctp_ulpevent *event = sctp_skb2event(skb); 405331c4ee7SVlad Yasevich 406d55d87fdSHerbert Xu skb_orphan(skb); 407331c4ee7SVlad Yasevich skb->sk = sk; 408331c4ee7SVlad Yasevich skb->destructor = sctp_sock_rfree; 409331c4ee7SVlad Yasevich atomic_add(event->rmem_len, &sk->sk_rmem_alloc); 4104d93df0aSNeil Horman /* 4113ab224beSHideo Aoki * This mimics the behavior of skb_set_owner_r 4124d93df0aSNeil Horman */ 4139dde27deSXin Long sk_mem_charge(sk, event->rmem_len); 414331c4ee7SVlad Yasevich } 415331c4ee7SVlad Yasevich 4161da177e4SLinus Torvalds /* Tests if the list has one and only one entry. */ 4171da177e4SLinus Torvalds static inline int sctp_list_single_entry(struct list_head *head) 4181da177e4SLinus Torvalds { 4196fc3e68fSGeliang Tang return list_is_singular(head); 4201da177e4SLinus Torvalds } 4211da177e4SLinus Torvalds 422b69040d8SDaniel Borkmann static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk) 423b69040d8SDaniel Borkmann { 424b69040d8SDaniel Borkmann return !list_empty(&chunk->list); 425b69040d8SDaniel Borkmann } 426b69040d8SDaniel Borkmann 4271da177e4SLinus Torvalds /* Walk through a list of TLV parameters. Don't trust the 4281da177e4SLinus Torvalds * individual parameter lengths and instead depend on 4291da177e4SLinus Torvalds * the chunk length to indicate when to stop. Make sure 4301da177e4SLinus Torvalds * there is room for a param header too. 4311da177e4SLinus Torvalds */ 4321da177e4SLinus Torvalds #define sctp_walk_params(pos, chunk, member)\ 433dd2d1c6fSVladislav Yasevich _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member) 4341da177e4SLinus Torvalds 4351da177e4SLinus Torvalds #define _sctp_walk_params(pos, chunk, end, member)\ 4361da177e4SLinus Torvalds for (pos.v = chunk->member;\ 4376b84202cSXin Long (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\ 438b1f5bfc2SAlexander Potapenko (void *)chunk + end) &&\ 439dd2d1c6fSVladislav Yasevich pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\ 4403c918704SXin Long ntohs(pos.p->length) >= sizeof(struct sctp_paramhdr);\ 441e2f036a9SMarcelo Ricardo Leitner pos.v += SCTP_PAD4(ntohs(pos.p->length))) 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds #define sctp_walk_errors(err, chunk_hdr)\ 4441da177e4SLinus Torvalds _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length)) 4451da177e4SLinus Torvalds 4461da177e4SLinus Torvalds #define _sctp_walk_errors(err, chunk_hdr, end)\ 447d8238d9dSXin Long for (err = (struct sctp_errhdr *)((void *)chunk_hdr + \ 448922dbc5bSXin Long sizeof(struct sctp_chunkhdr));\ 449d8238d9dSXin Long ((void *)err + offsetof(struct sctp_errhdr, length) + sizeof(err->length) <=\ 450b1f5bfc2SAlexander Potapenko (void *)chunk_hdr + end) &&\ 451dd2d1c6fSVladislav Yasevich (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\ 452d8238d9dSXin Long ntohs(err->length) >= sizeof(struct sctp_errhdr); \ 453d8238d9dSXin Long err = (struct sctp_errhdr *)((void *)err + SCTP_PAD4(ntohs(err->length)))) 4541da177e4SLinus Torvalds 4551da177e4SLinus Torvalds #define sctp_walk_fwdtsn(pos, chunk)\ 4561da177e4SLinus Torvalds _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk)) 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds #define _sctp_walk_fwdtsn(pos, chunk, end)\ 4591da177e4SLinus Torvalds for (pos = chunk->subh.fwdtsn_hdr->skip;\ 4601da177e4SLinus Torvalds (void *)pos <= (void *)chunk->subh.fwdtsn_hdr->skip + end - sizeof(struct sctp_fwdtsn_skip);\ 4611da177e4SLinus Torvalds pos++) 4621da177e4SLinus Torvalds 4631da177e4SLinus Torvalds /* External references. */ 4641da177e4SLinus Torvalds 4651da177e4SLinus Torvalds extern struct proto sctp_prot; 4661da177e4SLinus Torvalds extern struct proto sctpv6_prot; 4671da177e4SLinus Torvalds void sctp_put_port(struct sock *sk); 4681da177e4SLinus Torvalds 4691da177e4SLinus Torvalds extern struct idr sctp_assocs_id; 4701da177e4SLinus Torvalds extern spinlock_t sctp_assocs_id_lock; 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds /* Static inline functions. */ 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds /* Convert from an IP version number to an Address Family symbol. */ 4751da177e4SLinus Torvalds static inline int ipver2af(__u8 ipver) 4761da177e4SLinus Torvalds { 4771da177e4SLinus Torvalds switch (ipver) { 4781da177e4SLinus Torvalds case 4: 4791da177e4SLinus Torvalds return AF_INET; 4801da177e4SLinus Torvalds case 6: 4811da177e4SLinus Torvalds return AF_INET6; 4821da177e4SLinus Torvalds default: 4831da177e4SLinus Torvalds return 0; 484e3cc055cSJoe Perches } 4851da177e4SLinus Torvalds } 4861da177e4SLinus Torvalds 4871da177e4SLinus Torvalds /* Convert from an address parameter type to an address family. */ 488dbc16db1SAl Viro static inline int param_type2af(__be16 type) 4891da177e4SLinus Torvalds { 4901da177e4SLinus Torvalds switch (type) { 4911da177e4SLinus Torvalds case SCTP_PARAM_IPV4_ADDRESS: 4921da177e4SLinus Torvalds return AF_INET; 4931da177e4SLinus Torvalds case SCTP_PARAM_IPV6_ADDRESS: 4941da177e4SLinus Torvalds return AF_INET6; 4951da177e4SLinus Torvalds default: 4961da177e4SLinus Torvalds return 0; 497e3cc055cSJoe Perches } 4981da177e4SLinus Torvalds } 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds /* Warning: The following hash functions assume a power of two 'size'. */ 5011da177e4SLinus Torvalds /* This is the hash function for the SCTP port hash table. */ 502f1f43763SEric W. Biederman static inline int sctp_phashfn(struct net *net, __u16 lport) 5031da177e4SLinus Torvalds { 504f1f43763SEric W. Biederman return (net_hash_mix(net) + lport) & (sctp_port_hashsize - 1); 5051da177e4SLinus Torvalds } 5061da177e4SLinus Torvalds 5071da177e4SLinus Torvalds /* This is the hash function for the endpoint hash table. */ 5084cdadcbcSEric W. Biederman static inline int sctp_ep_hashfn(struct net *net, __u16 lport) 5091da177e4SLinus Torvalds { 5104cdadcbcSEric W. Biederman return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1); 5111da177e4SLinus Torvalds } 5121da177e4SLinus Torvalds 513*3d3b2f57SXin Long #define sctp_for_each_hentry(ep, head) \ 514*3d3b2f57SXin Long hlist_for_each_entry(ep, head, node) 515d970dbf8SVlad Yasevich 5161da177e4SLinus Torvalds /* Is a socket of this style? */ 5171da177e4SLinus Torvalds #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) 518b7ef2618SXin Long static inline int __sctp_style(const struct sock *sk, 519b7ef2618SXin Long enum sctp_socket_type style) 5201da177e4SLinus Torvalds { 5211da177e4SLinus Torvalds return sctp_sk(sk)->type == style; 5221da177e4SLinus Torvalds } 5231da177e4SLinus Torvalds 5241da177e4SLinus Torvalds /* Is the association in this state? */ 5251da177e4SLinus Torvalds #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state)) 5261da177e4SLinus Torvalds static inline int __sctp_state(const struct sctp_association *asoc, 52752106019SXin Long enum sctp_state state) 5281da177e4SLinus Torvalds { 5291da177e4SLinus Torvalds return asoc->state == state; 5301da177e4SLinus Torvalds } 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds /* Is the socket in this state? */ 5331da177e4SLinus Torvalds #define sctp_sstate(sk, state) __sctp_sstate((sk), (SCTP_SS_##state)) 53484965614SXin Long static inline int __sctp_sstate(const struct sock *sk, 53584965614SXin Long enum sctp_sock_state state) 5361da177e4SLinus Torvalds { 5371da177e4SLinus Torvalds return sk->sk_state == state; 5381da177e4SLinus Torvalds } 5391da177e4SLinus Torvalds 5401da177e4SLinus Torvalds /* Map v4-mapped v6 address back to v4 address */ 5411da177e4SLinus Torvalds static inline void sctp_v6_map_v4(union sctp_addr *addr) 5421da177e4SLinus Torvalds { 5431da177e4SLinus Torvalds addr->v4.sin_family = AF_INET; 5441da177e4SLinus Torvalds addr->v4.sin_port = addr->v6.sin6_port; 5451da177e4SLinus Torvalds addr->v4.sin_addr.s_addr = addr->v6.sin6_addr.s6_addr32[3]; 5461da177e4SLinus Torvalds } 5471da177e4SLinus Torvalds 5481da177e4SLinus Torvalds /* Map v4 address to v4-mapped v6 address */ 5491da177e4SLinus Torvalds static inline void sctp_v4_map_v6(union sctp_addr *addr) 5501da177e4SLinus Torvalds { 5519302d7bbSJason Gunthorpe __be16 port; 5529302d7bbSJason Gunthorpe 5539302d7bbSJason Gunthorpe port = addr->v4.sin_port; 5549302d7bbSJason Gunthorpe addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; 5559302d7bbSJason Gunthorpe addr->v6.sin6_port = port; 5561da177e4SLinus Torvalds addr->v6.sin6_family = AF_INET6; 557299ee123SJason Gunthorpe addr->v6.sin6_flowinfo = 0; 558299ee123SJason Gunthorpe addr->v6.sin6_scope_id = 0; 5591da177e4SLinus Torvalds addr->v6.sin6_addr.s6_addr32[0] = 0; 5601da177e4SLinus Torvalds addr->v6.sin6_addr.s6_addr32[1] = 0; 5611da177e4SLinus Torvalds addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff); 5621da177e4SLinus Torvalds } 5631da177e4SLinus Torvalds 564e0268868SNicolas Dichtel /* The cookie is always 0 since this is how it's used in the 565e0268868SNicolas Dichtel * pmtu code. 566e0268868SNicolas Dichtel */ 567e0268868SNicolas Dichtel static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) 568e0268868SNicolas Dichtel { 569df2729c3SXin Long if (t->dst && !dst_check(t->dst, t->dst_cookie)) 570c86a773cSJulian Anastasov sctp_transport_dst_release(t); 571e0268868SNicolas Dichtel 572e0268868SNicolas Dichtel return t->dst; 573e0268868SNicolas Dichtel } 574e0268868SNicolas Dichtel 575feddd6c1SMarcelo Ricardo Leitner /* Calculate max payload size given a MTU, or the total overhead if 576feddd6c1SMarcelo Ricardo Leitner * given MTU is zero 577feddd6c1SMarcelo Ricardo Leitner */ 578d9e2e410SXin Long static inline __u32 __sctp_mtu_payload(const struct sctp_sock *sp, 579d9e2e410SXin Long const struct sctp_transport *t, 580feddd6c1SMarcelo Ricardo Leitner __u32 mtu, __u32 extra) 581df2729c3SXin Long { 582feddd6c1SMarcelo Ricardo Leitner __u32 overhead = sizeof(struct sctphdr) + extra; 583df2729c3SXin Long 584f1bfe8b5SXin Long if (sp) { 585feddd6c1SMarcelo Ricardo Leitner overhead += sp->pf->af->net_header_len; 586d9e2e410SXin Long if (sp->udp_port && (!t || t->encap_port)) 587f1bfe8b5SXin Long overhead += sizeof(struct udphdr); 588f1bfe8b5SXin Long } else { 589feddd6c1SMarcelo Ricardo Leitner overhead += sizeof(struct ipv6hdr); 590f1bfe8b5SXin Long } 591df2729c3SXin Long 592feddd6c1SMarcelo Ricardo Leitner if (WARN_ON_ONCE(mtu && mtu <= overhead)) 593feddd6c1SMarcelo Ricardo Leitner mtu = overhead; 594df2729c3SXin Long 595feddd6c1SMarcelo Ricardo Leitner return mtu ? mtu - overhead : overhead; 596feddd6c1SMarcelo Ricardo Leitner } 597feddd6c1SMarcelo Ricardo Leitner 598d9e2e410SXin Long static inline __u32 sctp_mtu_payload(const struct sctp_sock *sp, 599d9e2e410SXin Long __u32 mtu, __u32 extra) 600d9e2e410SXin Long { 601d9e2e410SXin Long return __sctp_mtu_payload(sp, NULL, mtu, extra); 602d9e2e410SXin Long } 603d9e2e410SXin Long 6046ff0f871SMarcelo Ricardo Leitner static inline __u32 sctp_dst_mtu(const struct dst_entry *dst) 6056ff0f871SMarcelo Ricardo Leitner { 6066ff0f871SMarcelo Ricardo Leitner return SCTP_TRUNC4(max_t(__u32, dst_mtu(dst), 6076ff0f871SMarcelo Ricardo Leitner SCTP_DEFAULT_MINSEGMENT)); 608df2729c3SXin Long } 609df2729c3SXin Long 61069fec325SXin Long static inline bool sctp_transport_pmtu_check(struct sctp_transport *t) 61169fec325SXin Long { 61269fec325SXin Long __u32 pmtu = sctp_dst_mtu(t->dst); 61369fec325SXin Long 61469fec325SXin Long if (t->pathmtu == pmtu) 61569fec325SXin Long return true; 61669fec325SXin Long 61769fec325SXin Long t->pathmtu = pmtu; 61869fec325SXin Long 61969fec325SXin Long return false; 62069fec325SXin Long } 62169fec325SXin Long 622afd0a800SJakub Audykowicz static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize) 623afd0a800SJakub Audykowicz { 624afd0a800SJakub Audykowicz return sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, datasize); 625afd0a800SJakub Audykowicz } 626afd0a800SJakub Audykowicz 627d9e2e410SXin Long static inline int sctp_transport_pl_hlen(struct sctp_transport *t) 628d9e2e410SXin Long { 629cc4665caSXin Long return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0) - 630cc4665caSXin Long sizeof(struct sctphdr); 631d9e2e410SXin Long } 632d9e2e410SXin Long 633d9e2e410SXin Long static inline void sctp_transport_pl_reset(struct sctp_transport *t) 634d9e2e410SXin Long { 635d9e2e410SXin Long if (t->probe_interval && (t->param_flags & SPP_PMTUD_ENABLE) && 636d9e2e410SXin Long (t->state == SCTP_ACTIVE || t->state == SCTP_UNKNOWN)) { 637d9e2e410SXin Long if (t->pl.state == SCTP_PL_DISABLED) { 638d9e2e410SXin Long t->pl.state = SCTP_PL_BASE; 639d9e2e410SXin Long t->pl.pmtu = SCTP_BASE_PLPMTU; 640d9e2e410SXin Long t->pl.probe_size = SCTP_BASE_PLPMTU; 64192548ec2SXin Long sctp_transport_reset_probe_timer(t); 642d9e2e410SXin Long } 643d9e2e410SXin Long } else { 64492548ec2SXin Long if (t->pl.state != SCTP_PL_DISABLED) { 64592548ec2SXin Long if (del_timer(&t->probe_timer)) 64692548ec2SXin Long sctp_transport_put(t); 647d9e2e410SXin Long t->pl.state = SCTP_PL_DISABLED; 648d9e2e410SXin Long } 649d9e2e410SXin Long } 65092548ec2SXin Long } 651d9e2e410SXin Long 652d9e2e410SXin Long static inline void sctp_transport_pl_update(struct sctp_transport *t) 653d9e2e410SXin Long { 654d9e2e410SXin Long if (t->pl.state == SCTP_PL_DISABLED) 655d9e2e410SXin Long return; 656d9e2e410SXin Long 657d9e2e410SXin Long t->pl.state = SCTP_PL_BASE; 658d9e2e410SXin Long t->pl.pmtu = SCTP_BASE_PLPMTU; 659d9e2e410SXin Long t->pl.probe_size = SCTP_BASE_PLPMTU; 660c6ea04eaSXin Long sctp_transport_reset_probe_timer(t); 661d9e2e410SXin Long } 662d9e2e410SXin Long 663d9e2e410SXin Long static inline bool sctp_transport_pl_enabled(struct sctp_transport *t) 664d9e2e410SXin Long { 665d9e2e410SXin Long return t->pl.state != SCTP_PL_DISABLED; 666d9e2e410SXin Long } 667d9e2e410SXin Long 668819be810SXin Long static inline bool sctp_newsk_ready(const struct sock *sk) 669819be810SXin Long { 670819be810SXin Long return sock_flag(sk, SOCK_DEAD) || sk->sk_socket; 671819be810SXin Long } 672819be810SXin Long 67340ef92c6SChristoph Hellwig static inline void sctp_sock_set_nodelay(struct sock *sk) 67440ef92c6SChristoph Hellwig { 67540ef92c6SChristoph Hellwig lock_sock(sk); 67640ef92c6SChristoph Hellwig sctp_sk(sk)->nodelay = true; 67740ef92c6SChristoph Hellwig release_sock(sk); 67840ef92c6SChristoph Hellwig } 67940ef92c6SChristoph Hellwig 6801da177e4SLinus Torvalds #endif /* __net_sctp_h__ */ 681