sctputil.h revision 283708
1192811Srmacklem/*- 2192811Srmacklem * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3192811Srmacklem * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4192811Srmacklem * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5192811Srmacklem * 6192811Srmacklem * Redistribution and use in source and binary forms, with or without 7192811Srmacklem * modification, are permitted provided that the following conditions are met: 8192811Srmacklem * 9192811Srmacklem * a) Redistributions of source code must retain the above copyright notice, 10192811Srmacklem * this list of conditions and the following disclaimer. 11192811Srmacklem * 12192811Srmacklem * b) Redistributions in binary form must reproduce the above copyright 13192811Srmacklem * notice, this list of conditions and the following disclaimer in 14192811Srmacklem * the documentation and/or other materials provided with the distribution. 15192811Srmacklem * 16192811Srmacklem * c) Neither the name of Cisco Systems, Inc. nor the names of its 17192811Srmacklem * contributors may be used to endorse or promote products derived 18192811Srmacklem * from this software without specific prior written permission. 19192811Srmacklem * 20192811Srmacklem * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21192811Srmacklem * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22192811Srmacklem * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23192811Srmacklem * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24192811Srmacklem * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25192811Srmacklem * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26192811Srmacklem * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27192811Srmacklem * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28192811Srmacklem * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29192811Srmacklem * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30192811Srmacklem * THE POSSIBILITY OF SUCH DAMAGE. 31192811Srmacklem */ 32192811Srmacklem 33192811Srmacklem#include <sys/cdefs.h> 34192811Srmacklem__FBSDID("$FreeBSD: stable/10/sys/netinet/sctputil.h 283708 2015-05-29 12:03:02Z tuexen $"); 35192811Srmacklem 36192811Srmacklem#ifndef _NETINET_SCTP_UTIL_H_ 37192811Srmacklem#define _NETINET_SCTP_UTIL_H_ 38192811Srmacklem 39192811Srmacklem#if defined(_KERNEL) || defined(__Userspace__) 40192811Srmacklem 41192811Srmacklem#define SCTP_READ_LOCK_HELD 1 42192811Srmacklem#define SCTP_READ_LOCK_NOT_HELD 0 43192811Srmacklem 44192811Srmacklem#ifdef SCTP_ASOCLOG_OF_TSNS 45192811Srmacklemvoid sctp_print_out_track_log(struct sctp_tcb *stcb); 46192811Srmacklem 47192811Srmacklem#endif 48192811Srmacklem 49192811Srmacklem#ifdef SCTP_MBUF_LOGGING 50192811Srmacklemstruct mbuf *sctp_m_free(struct mbuf *m); 51192811Srmacklemvoid sctp_m_freem(struct mbuf *m); 52192811Srmacklem 53192811Srmacklem#else 54192811Srmacklem#define sctp_m_free m_free 55192811Srmacklem#define sctp_m_freem m_freem 56192811Srmacklem#endif 57192811Srmacklem 58192811Srmacklem#if defined(SCTP_LOCAL_TRACE_BUF) || defined(__APPLE__) 59192811Srmacklemvoid 60192811Srmacklem sctp_log_trace(uint32_t fr, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f); 61192811Srmacklem 62192811Srmacklem#endif 63192811Srmacklem 64192811Srmacklem#define sctp_get_associd(stcb) ((sctp_assoc_t)stcb->asoc.assoc_id) 65192811Srmacklem 66192811Srmacklem 67192811Srmacklem/* 68192811Srmacklem * Function prototypes 69193070Sdelphij */ 70193070Sdelphijuint32_t 71193070Sdelphijsctp_get_ifa_hash_val(struct sockaddr *addr); 72193070Sdelphij 73193070Sdelphijstruct sctp_ifa * 74193070Sdelphij sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr, int hold_lock); 75192811Srmacklem 76192811Srmacklemstruct sctp_ifa * 77192811Srmacklem sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock); 78192811Srmacklem 79223382Srmacklemuint32_t sctp_select_initial_TSN(struct sctp_pcb *); 80223382Srmacklem 81192811Srmacklemuint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int); 82192811Srmacklem 83192811Srmacklemint sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t); 84192811Srmacklem 85192811Srmacklemvoid sctp_fill_random_store(struct sctp_pcb *); 86192811Srmacklem 87192811Srmacklemvoid 88192811Srmacklemsctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, 89192811Srmacklem uint16_t numberout, int flag); 90192811Srmacklemvoid 91192811Srmacklem sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag); 92192811Srmacklem 93192811Srmacklemvoid 94192811Srmacklemsctp_timer_start(int, struct sctp_inpcb *, struct sctp_tcb *, 95192811Srmacklem struct sctp_nets *); 96192811Srmacklem 97192811Srmacklemvoid 98192811Srmacklemsctp_timer_stop(int, struct sctp_inpcb *, struct sctp_tcb *, 99193070Sdelphij struct sctp_nets *, uint32_t); 100192811Srmacklem 101223382Srmacklemint 102223382Srmacklem sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id); 103192811Srmacklem 104192811Srmacklemvoid 105192811Srmacklem sctp_mtu_size_reset(struct sctp_inpcb *, struct sctp_association *, uint32_t); 106192811Srmacklem 107193070Sdelphijvoid 108192811Srmacklemsctp_add_to_readq(struct sctp_inpcb *inp, 109192811Srmacklem struct sctp_tcb *stcb, 110193070Sdelphij struct sctp_queued_to_read *control, 111192811Srmacklem struct sockbuf *sb, 112223382Srmacklem int end, 113192811Srmacklem int inpread_locked, 114192811Srmacklem int so_locked 115192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 116192811Srmacklem SCTP_UNUSED 117192811Srmacklem#endif 118192811Srmacklem); 119192811Srmacklem 120192811Srmacklemint 121192811Srmacklemsctp_append_to_readq(struct sctp_inpcb *inp, 122192811Srmacklem struct sctp_tcb *stcb, 123192811Srmacklem struct sctp_queued_to_read *control, 124192811Srmacklem struct mbuf *m, 125192811Srmacklem int end, 126192811Srmacklem int new_cumack, 127192811Srmacklem struct sockbuf *sb); 128192811Srmacklem 129192811Srmacklem 130192811Srmacklemvoid sctp_iterator_worker(void); 131192811Srmacklem 132192811Srmacklemuint32_t sctp_get_prev_mtu(uint32_t); 133192811Srmacklemuint32_t sctp_get_next_mtu(uint32_t); 134192811Srmacklem 135192811Srmacklemvoid 136192811Srmacklem sctp_timeout_handler(void *); 137192811Srmacklem 138192811Srmacklemuint32_t 139192811Srmacklemsctp_calculate_rto(struct sctp_tcb *, struct sctp_association *, 140192811Srmacklem struct sctp_nets *, struct timeval *, int, int); 141192811Srmacklem 142192811Srmacklemuint32_t sctp_calculate_len(struct mbuf *); 143192811Srmacklem 144192811Srmacklemcaddr_t sctp_m_getptr(struct mbuf *, int, int, uint8_t *); 145192811Srmacklem 146192811Srmacklemstruct sctp_paramhdr * 147192811Srmacklemsctp_get_next_param(struct mbuf *, int, 148192811Srmacklem struct sctp_paramhdr *, int); 149192811Srmacklem 150192811Srmacklemstruct mbuf * 151192811Srmacklem sctp_add_pad_tombuf(struct mbuf *, int); 152192811Srmacklem 153192811Srmacklemstruct mbuf * 154192811Srmacklem sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *); 155192811Srmacklem 156192811Srmacklemvoid 157192811Srmacklemsctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *, int 158192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 159192811Srmacklem SCTP_UNUSED 160192811Srmacklem#endif 161192811Srmacklem); 162192811Srmacklem 163192811Srmacklemvoid 164192811Srmacklemsctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, 165192811Srmacklem struct sctp_inpcb *new_inp, 166192811Srmacklem struct sctp_tcb *stcb, int waitflags); 167192811Srmacklem 168192811Srmacklem 169223382Srmacklemvoid sctp_stop_timers_for_shutdown(struct sctp_tcb *); 170192811Srmacklem 171223382Srmacklemvoid 172223382Srmacklemsctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int 173192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 174192811Srmacklem SCTP_UNUSED 175192811Srmacklem#endif 176192811Srmacklem); 177192811Srmacklem 178192811Srmacklemint sctp_expand_mapping_array(struct sctp_association *, uint32_t); 179192811Srmacklem 180192811Srmacklemvoid 181192811Srmacklemsctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t, 182192811Srmacklem struct sctp_abort_chunk *, int 183192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 184193070Sdelphij SCTP_UNUSED 185192811Srmacklem#endif 186192811Srmacklem); 187192811Srmacklem 188192811Srmacklem/* We abort responding to an IP packet for some reason */ 189192811Srmacklemvoid 190192811Srmacklemsctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *, 191192811Srmacklem int, struct sockaddr *, struct sockaddr *, 192192811Srmacklem struct sctphdr *, struct mbuf *, 193192811Srmacklem uint8_t, uint32_t, 194192811Srmacklem uint32_t, uint16_t); 195192811Srmacklem 196192811Srmacklem 197192811Srmacklem/* We choose to abort via user input */ 198192811Srmacklemvoid 199192811Srmacklemsctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *, 200192811Srmacklem struct mbuf *, int 201192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 202192811Srmacklem SCTP_UNUSED 203192811Srmacklem#endif 204192811Srmacklem); 205192811Srmacklem 206192811Srmacklemvoid 207192811Srmacklemsctp_handle_ootb(struct mbuf *, int, int, 208192811Srmacklem struct sockaddr *, struct sockaddr *, 209192811Srmacklem struct sctphdr *, struct sctp_inpcb *, 210192811Srmacklem struct mbuf *, 211192811Srmacklem uint8_t, uint32_t, 212192811Srmacklem uint32_t, uint16_t); 213192811Srmacklem 214192811Srmacklemint 215192811Srmacklemsctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, 216192811Srmacklem int totaddr, int *error); 217192811Srmacklem 218192811Srmacklemstruct sctp_tcb * 219192811Srmacklemsctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, 220192811Srmacklem int *totaddr, int *num_v4, int *num_v6, int *error, int limit, int *bad_addr); 221192811Srmacklem 222192811Srmacklemint sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *); 223192811Srmacklem 224192811Srmacklem#ifdef INET6 225192811Srmacklemuint32_t sctp_is_same_scope(struct sockaddr_in6 *, struct sockaddr_in6 *); 226192811Srmacklem 227192811Srmacklemstruct sockaddr_in6 * 228192811Srmacklem sctp_recover_scope(struct sockaddr_in6 *, struct sockaddr_in6 *); 229192811Srmacklem 230192811Srmacklem#define sctp_recover_scope_mac(addr, store) do { \ 231192811Srmacklem if ((addr->sin6_family == AF_INET6) && \ 232192811Srmacklem (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr))) { \ 233192811Srmacklem *store = *addr; \ 234192811Srmacklem if (addr->sin6_scope_id == 0) { \ 235192811Srmacklem if (!sa6_recoverscope(store)) { \ 236192811Srmacklem addr = store; \ 237192811Srmacklem } \ 238192811Srmacklem } else { \ 239192811Srmacklem in6_clearscope(&addr->sin6_addr); \ 240192811Srmacklem addr = store; \ 241192811Srmacklem } \ 242192811Srmacklem } \ 243192811Srmacklem} while (0) 244192811Srmacklem#endif 245192811Srmacklem 246192811Srmacklemint sctp_cmpaddr(struct sockaddr *, struct sockaddr *); 247192811Srmacklem 248192811Srmacklemvoid sctp_print_address(struct sockaddr *); 249192811Srmacklem 250192811Srmacklemint 251192811Srmacklemsctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *, 252192811Srmacklem uint8_t, int 253192811Srmacklem#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 254192811Srmacklem SCTP_UNUSED 255192811Srmacklem#endif 256192811Srmacklem); 257192811Srmacklem 258192811Srmacklemstruct mbuf *sctp_generate_cause(uint16_t, char *); 259192811Srmacklemstruct mbuf *sctp_generate_no_user_data_cause(uint32_t); 260192811Srmacklem 261192811Srmacklemvoid 262192811Srmacklemsctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, 263192811Srmacklem struct sockaddr *sa, sctp_assoc_t assoc_id, 264192811Srmacklem uint32_t vrf_id, int *error, void *p); 265192811Srmacklemvoid 266192811Srmacklemsctp_bindx_delete_address(struct sctp_inpcb *inp, 267192811Srmacklem struct sockaddr *sa, sctp_assoc_t assoc_id, 268192811Srmacklem uint32_t vrf_id, int *error); 269192811Srmacklem 270192811Srmacklemint sctp_local_addr_count(struct sctp_tcb *stcb); 271192811Srmacklem 272192811Srmacklem#ifdef SCTP_MBCNT_LOGGING 273192811Srmacklemvoid 274192811Srmacklemsctp_free_bufspace(struct sctp_tcb *, struct sctp_association *, 275192811Srmacklem struct sctp_tmit_chunk *, int); 276192811Srmacklem 277192811Srmacklem#else 278192811Srmacklem#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt) \ 279192811Srmacklemdo { \ 280192811Srmacklem if (tp1->data != NULL) { \ 281192811Srmacklem atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \ 282192811Srmacklem if ((asoc)->total_output_queue_size >= tp1->book_size) { \ 283192811Srmacklem atomic_subtract_int(&((asoc)->total_output_queue_size), tp1->book_size); \ 284192811Srmacklem } else { \ 285192811Srmacklem (asoc)->total_output_queue_size = 0; \ 286192811Srmacklem } \ 287192811Srmacklem if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ 288192811Srmacklem (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ 289192811Srmacklem if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { \ 290192811Srmacklem atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_cc), tp1->book_size); \ 291192811Srmacklem } else { \ 292192811Srmacklem stcb->sctp_socket->so_snd.sb_cc = 0; \ 293192811Srmacklem } \ 294192811Srmacklem } \ 295192811Srmacklem } \ 296192811Srmacklem} while (0) 297192811Srmacklem 298192811Srmacklem#endif 299192811Srmacklem 300192811Srmacklem#define sctp_free_spbufspace(stcb, asoc, sp) \ 301192811Srmacklemdo { \ 302192811Srmacklem if (sp->data != NULL) { \ 303192811Srmacklem if ((asoc)->total_output_queue_size >= sp->length) { \ 304192811Srmacklem atomic_subtract_int(&(asoc)->total_output_queue_size, sp->length); \ 305192811Srmacklem } else { \ 306192811Srmacklem (asoc)->total_output_queue_size = 0; \ 307192811Srmacklem } \ 308192811Srmacklem if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ 309192811Srmacklem (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ 310192811Srmacklem if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \ 311192811Srmacklem atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \ 312192811Srmacklem } else { \ 313192811Srmacklem stcb->sctp_socket->so_snd.sb_cc = 0; \ 314192811Srmacklem } \ 315192811Srmacklem } \ 316192811Srmacklem } \ 317192811Srmacklem} while (0) 318192811Srmacklem 319192811Srmacklem#define sctp_snd_sb_alloc(stcb, sz) \ 320192811Srmacklemdo { \ 321192811Srmacklem atomic_add_int(&stcb->asoc.total_output_queue_size,sz); \ 322192811Srmacklem if ((stcb->sctp_socket != NULL) && \ 323192811Srmacklem ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ 324192811Srmacklem (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ 325192811Srmacklem atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \ 326192811Srmacklem } \ 327192811Srmacklem} while (0) 328192811Srmacklem 329192811Srmacklem/* functions to start/stop udp tunneling */ 330192811Srmacklemvoid sctp_over_udp_stop(void); 331192811Srmacklemint sctp_over_udp_start(void); 332192811Srmacklem 333223382Srmacklemint 334192811Srmacklemsctp_soreceive(struct socket *so, struct sockaddr **psa, 335192811Srmacklem struct uio *uio, 336223382Srmacklem struct mbuf **mp0, 337223382Srmacklem struct mbuf **controlp, 338223382Srmacklem int *flagsp); 339223382Srmacklem 340223382Srmacklemvoid 341223382Srmacklem sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d); 342223382Srmacklem 343223382Srmacklemvoid 344223382Srmacklemsctp_wakeup_log(struct sctp_tcb *stcb, 345223382Srmacklem uint32_t wake_cnt, int from); 346223382Srmacklem 347223382Srmacklemvoid sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t, uint16_t, uint16_t, int); 348223382Srmacklem 349223382Srmacklemvoid sctp_log_nagle_event(struct sctp_tcb *stcb, int action); 350223382Srmacklem 351223382Srmacklem 352192811Srmacklem#ifdef SCTP_MBUF_LOGGING 353192811Srmacklemvoid 354192811Srmacklem sctp_log_mb(struct mbuf *m, int from); 355192811Srmacklem 356192811Srmacklemvoid 357192811Srmacklem sctp_log_mbc(struct mbuf *m, int from); 358192811Srmacklem 359192811Srmacklem#endif 360192811Srmacklem 361192811Srmacklemvoid 362192811Srmacklemsctp_sblog(struct sockbuf *sb, 363192811Srmacklem struct sctp_tcb *stcb, int from, int incr); 364192811Srmacklem 365192811Srmacklemvoid 366192811Srmacklemsctp_log_strm_del(struct sctp_queued_to_read *control, 367192811Srmacklem struct sctp_queued_to_read *poschk, 368192811Srmacklem int from); 369192811Srmacklemvoid sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *, int, uint8_t); 370192811Srmacklemvoid rto_logging(struct sctp_nets *net, int from); 371192811Srmacklem 372192811Srmacklemvoid sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc); 373192811Srmacklem 374192811Srmacklemvoid sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from); 375192811Srmacklemvoid sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *, int, int, uint8_t); 376192811Srmacklemvoid sctp_log_block(uint8_t, struct sctp_association *, int); 377192811Srmacklemvoid sctp_log_rwnd(uint8_t, uint32_t, uint32_t, uint32_t); 378192811Srmacklemvoid sctp_log_rwnd_set(uint8_t, uint32_t, uint32_t, uint32_t, uint32_t); 379192811Srmacklemint sctp_fill_stat_log(void *, size_t *); 380192811Srmacklemvoid sctp_log_fr(uint32_t, uint32_t, uint32_t, int); 381192811Srmacklemvoid sctp_log_sack(uint32_t, uint32_t, uint32_t, uint16_t, uint16_t, int); 382192811Srmacklemvoid sctp_log_map(uint32_t, uint32_t, uint32_t, int); 383192811Srmacklemvoid sctp_print_mapping_array(struct sctp_association *asoc); 384192811Srmacklemvoid sctp_clr_stat_log(void); 385192811Srmacklem 386192811Srmacklem 387192811Srmacklem#ifdef SCTP_AUDITING_ENABLED 388192811Srmacklemvoid 389192811Srmacklemsctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *, 390192811Srmacklem struct sctp_nets *); 391192811Srmacklemvoid sctp_audit_log(uint8_t, uint8_t); 392192811Srmacklem 393192811Srmacklem#endif 394192811Srmacklem#endif /* _KERNEL */ 395192811Srmacklem#endif 396192811Srmacklem