1163953Srrs/*- 2185694Srrs * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 3235828Stuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4235828Stuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5163953Srrs * 6163953Srrs * Redistribution and use in source and binary forms, with or without 7163953Srrs * modification, are permitted provided that the following conditions are met: 8163953Srrs * 9163953Srrs * a) Redistributions of source code must retain the above copyright notice, 10228653Stuexen * this list of conditions and the following disclaimer. 11163953Srrs * 12163953Srrs * b) Redistributions in binary form must reproduce the above copyright 13163953Srrs * notice, this list of conditions and the following disclaimer in 14228653Stuexen * the documentation and/or other materials provided with the distribution. 15163953Srrs * 16163953Srrs * c) Neither the name of Cisco Systems, Inc. nor the names of its 17163953Srrs * contributors may be used to endorse or promote products derived 18163953Srrs * from this software without specific prior written permission. 19163953Srrs * 20163953Srrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21163953Srrs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22163953Srrs * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23163953Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24163953Srrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25163953Srrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26163953Srrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27163953Srrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28163953Srrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29163953Srrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30163953Srrs * THE POSSIBILITY OF SUCH DAMAGE. 31163953Srrs */ 32163953Srrs 33163953Srrs#include <sys/cdefs.h> 34163953Srrs__FBSDID("$FreeBSD$"); 35163953Srrs 36163953Srrs#ifndef _NETINET_SCTP_VAR_H_ 37163953Srrs#define _NETINET_SCTP_VAR_H_ 38163953Srrs 39163953Srrs#include <netinet/sctp_uio.h> 40163953Srrs 41180387Srrs#if defined(_KERNEL) || defined(__Userspace__) 42163953Srrs 43163953Srrsextern struct pr_usrreqs sctp_usrreqs; 44163953Srrs 45163953Srrs 46163953Srrs#define sctp_feature_on(inp, feature) (inp->sctp_features |= feature) 47163953Srrs#define sctp_feature_off(inp, feature) (inp->sctp_features &= ~feature) 48181054Srrs#define sctp_is_feature_on(inp, feature) ((inp->sctp_features & feature) == feature) 49163953Srrs#define sctp_is_feature_off(inp, feature) ((inp->sctp_features & feature) == 0) 50163953Srrs 51223132Stuexen#define sctp_stcb_feature_on(inp, stcb, feature) {\ 52223132Stuexen if (stcb) { \ 53223132Stuexen stcb->asoc.sctp_features |= feature; \ 54228907Stuexen } else if (inp) { \ 55223132Stuexen inp->sctp_features |= feature; \ 56223132Stuexen } \ 57223132Stuexen} 58223132Stuexen#define sctp_stcb_feature_off(inp, stcb, feature) {\ 59223132Stuexen if (stcb) { \ 60223132Stuexen stcb->asoc.sctp_features &= ~feature; \ 61228907Stuexen } else if (inp) { \ 62223132Stuexen inp->sctp_features &= ~feature; \ 63223132Stuexen } \ 64223132Stuexen} 65223132Stuexen#define sctp_stcb_is_feature_on(inp, stcb, feature) \ 66223132Stuexen (((stcb != NULL) && \ 67223132Stuexen ((stcb->asoc.sctp_features & feature) == feature)) || \ 68228907Stuexen ((stcb == NULL) && (inp != NULL) && \ 69223132Stuexen ((inp->sctp_features & feature) == feature))) 70223132Stuexen#define sctp_stcb_is_feature_off(inp, stcb, feature) \ 71223132Stuexen (((stcb != NULL) && \ 72223132Stuexen ((stcb->asoc.sctp_features & feature) == 0)) || \ 73228907Stuexen ((stcb == NULL) && (inp != NULL) && \ 74228907Stuexen ((inp->sctp_features & feature) == 0)) || \ 75270352Stuexen ((stcb == NULL) && (inp == NULL))) 76181054Srrs 77171990Srrs/* managing mobility_feature in inpcb (by micchie) */ 78171990Srrs#define sctp_mobility_feature_on(inp, feature) (inp->sctp_mobility_features |= feature) 79171990Srrs#define sctp_mobility_feature_off(inp, feature) (inp->sctp_mobility_features &= ~feature) 80171990Srrs#define sctp_is_mobility_feature_on(inp, feature) (inp->sctp_mobility_features & feature) 81171990Srrs#define sctp_is_mobility_feature_off(inp, feature) ((inp->sctp_mobility_features & feature) == 0) 82171990Srrs 83172396Srrs#define sctp_maxspace(sb) (max((sb)->sb_hiwat,SCTP_MINIMAL_RWND)) 84163953Srrs 85172703Srrs#define sctp_sbspace(asoc, sb) ((long) ((sctp_maxspace(sb) > (asoc)->sb_cc) ? (sctp_maxspace(sb) - (asoc)->sb_cc) : 0)) 86163953Srrs 87172396Srrs#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0)) 88172396Srrs 89295208Stuexen#define sctp_sbspace_sub(a,b) (((a) > (b)) ? ((a) - (b)) : 0) 90163953Srrs 91167598Srrs/* 92167598Srrs * I tried to cache the readq entries at one point. But the reality 93167598Srrs * is that it did not add any performance since this meant we had to 94167598Srrs * lock the STCB on read. And at that point once you have to do an 95167598Srrs * extra lock, it really does not matter if the lock is in the ZONE 96167598Srrs * stuff or in our code. Note that this same problem would occur with 97167598Srrs * an mbuf cache as well so it is not really worth doing, at least 98167598Srrs * right now :-D 99163953Srrs */ 100163953Srrs 101163953Srrs#define sctp_free_a_readq(_stcb, _readq) { \ 102179783Srrs SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \ 103166675Srrs SCTP_DECR_READQ_COUNT(); \ 104163953Srrs} 105163953Srrs 106163953Srrs#define sctp_alloc_a_readq(_stcb, _readq) { \ 107179783Srrs (_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \ 108163953Srrs if ((_readq)) { \ 109270352Stuexen SCTP_INCR_READQ_COUNT(); \ 110163953Srrs } \ 111163953Srrs} 112163953Srrs 113221627Stuexen#define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked) { \ 114185694Srrs if ((_strmoq)->holds_key_ref) { \ 115221627Stuexen sctp_auth_key_release(stcb, sp->auth_keyid, _so_locked); \ 116185694Srrs (_strmoq)->holds_key_ref = 0; \ 117185694Srrs } \ 118179783Srrs SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), (_strmoq)); \ 119168859Srrs SCTP_DECR_STRMOQ_COUNT(); \ 120163953Srrs} 121163953Srrs 122163953Srrs#define sctp_alloc_a_strmoq(_stcb, _strmoq) { \ 123179783Srrs (_strmoq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_strmoq), struct sctp_stream_queue_pending); \ 124270352Stuexen if ((_strmoq)) { \ 125189790Srrs memset(_strmoq, 0, sizeof(struct sctp_stream_queue_pending)); \ 126168859Srrs SCTP_INCR_STRMOQ_COUNT(); \ 127185694Srrs (_strmoq)->holds_key_ref = 0; \ 128270352Stuexen } \ 129163953Srrs} 130163953Srrs 131221627Stuexen#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \ 132185694Srrs if ((_chk)->holds_key_ref) {\ 133221627Stuexen sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \ 134185694Srrs (_chk)->holds_key_ref = 0; \ 135185694Srrs } \ 136270352Stuexen if (_stcb) { \ 137270352Stuexen SCTP_TCB_LOCK_ASSERT((_stcb)); \ 138270352Stuexen if ((_chk)->whoTo) { \ 139270352Stuexen sctp_free_remote_addr((_chk)->whoTo); \ 140270352Stuexen (_chk)->whoTo = NULL; \ 141270352Stuexen } \ 142270352Stuexen if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \ 143270352Stuexen (SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \ 144270352Stuexen SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \ 145270352Stuexen SCTP_DECR_CHK_COUNT(); \ 146270352Stuexen } else { \ 147270352Stuexen TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \ 148270352Stuexen (_stcb)->asoc.free_chunk_cnt++; \ 149270352Stuexen atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \ 150270352Stuexen } \ 151270352Stuexen } else { \ 152179783Srrs SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \ 153163953Srrs SCTP_DECR_CHK_COUNT(); \ 154166675Srrs } \ 155163953Srrs} 156163953Srrs 157163953Srrs#define sctp_alloc_a_chunk(_stcb, _chk) { \ 158234464Stuexen if (TAILQ_EMPTY(&(_stcb)->asoc.free_chunks)) { \ 159179783Srrs (_chk) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_chunk), struct sctp_tmit_chunk); \ 160166675Srrs if ((_chk)) { \ 161166675Srrs SCTP_INCR_CHK_COUNT(); \ 162270352Stuexen (_chk)->whoTo = NULL; \ 163185694Srrs (_chk)->holds_key_ref = 0; \ 164166675Srrs } \ 165166675Srrs } else { \ 166166675Srrs (_chk) = TAILQ_FIRST(&(_stcb)->asoc.free_chunks); \ 167166675Srrs TAILQ_REMOVE(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \ 168179783Srrs atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \ 169185694Srrs (_chk)->holds_key_ref = 0; \ 170270352Stuexen SCTP_STAT_INCR(sctps_cached_chk); \ 171166675Srrs (_stcb)->asoc.free_chunk_cnt--; \ 172163953Srrs } \ 173163953Srrs} 174163953Srrs 175163953Srrs 176163953Srrs#define sctp_free_remote_addr(__net) { \ 177167598Srrs if ((__net)) { \ 178185694Srrs if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \ 179169378Srrs (void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \ 180169378Srrs (void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \ 181284505Stuexen (void)SCTP_OS_TIMER_STOP(&(__net)->hb_timer.timer); \ 182270352Stuexen if ((__net)->ro.ro_rt) { \ 183167598Srrs RTFREE((__net)->ro.ro_rt); \ 184167598Srrs (__net)->ro.ro_rt = NULL; \ 185270352Stuexen } \ 186167598Srrs if ((__net)->src_addr_selected) { \ 187167598Srrs sctp_free_ifa((__net)->ro._s_addr); \ 188167598Srrs (__net)->ro._s_addr = NULL; \ 189167598Srrs } \ 190270352Stuexen (__net)->src_addr_selected = 0; \ 191224641Stuexen (__net)->dest_state &= ~SCTP_ADDR_REACHABLE; \ 192179783Srrs SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \ 193163953Srrs SCTP_DECR_RADDR_COUNT(); \ 194163953Srrs } \ 195163953Srrs } \ 196163953Srrs} 197163953Srrs 198163953Srrs#define sctp_sbfree(ctl, stcb, sb, m) { \ 199185694Srrs SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \ 200185694Srrs SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \ 201166675Srrs if (((ctl)->do_not_ref_stcb == 0) && stcb) {\ 202185694Srrs SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \ 203185694Srrs SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ 204166675Srrs } \ 205165647Srrs if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ 206165647Srrs SCTP_BUF_TYPE(m) != MT_OOBDATA) \ 207165647Srrs atomic_subtract_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \ 208163953Srrs} 209163953Srrs 210163953Srrs#define sctp_sballoc(stcb, sb, m) { \ 211165647Srrs atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \ 212163953Srrs atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \ 213166675Srrs if (stcb) { \ 214166675Srrs atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \ 215171943Srrs atomic_add_int(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ 216166675Srrs } \ 217165647Srrs if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ 218165647Srrs SCTP_BUF_TYPE(m) != MT_OOBDATA) \ 219165647Srrs atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \ 220163953Srrs} 221163953Srrs 222163953Srrs 223163953Srrs#define sctp_ucount_incr(val) { \ 224163953Srrs val++; \ 225163953Srrs} 226163953Srrs 227163953Srrs#define sctp_ucount_decr(val) { \ 228163953Srrs if (val > 0) { \ 229163953Srrs val--; \ 230163953Srrs } else { \ 231163953Srrs val = 0; \ 232163953Srrs } \ 233163953Srrs} 234163953Srrs 235163953Srrs#define sctp_mbuf_crush(data) do { \ 236166675Srrs struct mbuf *_m; \ 237166675Srrs _m = (data); \ 238228907Stuexen while (_m && (SCTP_BUF_LEN(_m) == 0)) { \ 239166675Srrs (data) = SCTP_BUF_NEXT(_m); \ 240166675Srrs SCTP_BUF_NEXT(_m) = NULL; \ 241166675Srrs sctp_m_free(_m); \ 242163953Srrs _m = (data); \ 243166675Srrs } \ 244163953Srrs} while (0) 245163953Srrs 246168709Srrs#define sctp_flight_size_decrease(tp1) do { \ 247168709Srrs if (tp1->whoTo->flight_size >= tp1->book_size) \ 248168709Srrs tp1->whoTo->flight_size -= tp1->book_size; \ 249168709Srrs else \ 250168709Srrs tp1->whoTo->flight_size = 0; \ 251168709Srrs} while (0) 252163953Srrs 253171440Srrs#define sctp_flight_size_increase(tp1) do { \ 254270352Stuexen (tp1)->whoTo->flight_size += (tp1)->book_size; \ 255171440Srrs} while (0) 256168709Srrs 257171440Srrs#ifdef SCTP_FS_SPEC_LOG 258168709Srrs#define sctp_total_flight_decrease(stcb, tp1) do { \ 259270352Stuexen if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \ 260171440Srrs stcb->asoc.fs_index = 0;\ 261171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \ 262171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \ 263171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \ 264171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \ 265171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \ 266171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].decr = 1; \ 267171440Srrs stcb->asoc.fs_index++; \ 268270352Stuexen tp1->window_probe = 0; \ 269168709Srrs if (stcb->asoc.total_flight >= tp1->book_size) { \ 270168709Srrs stcb->asoc.total_flight -= tp1->book_size; \ 271168709Srrs if (stcb->asoc.total_flight_count > 0) \ 272168709Srrs stcb->asoc.total_flight_count--; \ 273168709Srrs } else { \ 274168709Srrs stcb->asoc.total_flight = 0; \ 275168709Srrs stcb->asoc.total_flight_count = 0; \ 276168709Srrs } \ 277168709Srrs} while (0) 278168709Srrs 279171440Srrs#define sctp_total_flight_increase(stcb, tp1) do { \ 280270352Stuexen if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \ 281171440Srrs stcb->asoc.fs_index = 0;\ 282171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \ 283171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \ 284171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \ 285171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \ 286171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \ 287171440Srrs stcb->asoc.fslog[stcb->asoc.fs_index].decr = 0; \ 288171440Srrs stcb->asoc.fs_index++; \ 289270352Stuexen (stcb)->asoc.total_flight_count++; \ 290270352Stuexen (stcb)->asoc.total_flight += (tp1)->book_size; \ 291168709Srrs} while (0) 292168709Srrs 293171440Srrs#else 294168709Srrs 295168709Srrs#define sctp_total_flight_decrease(stcb, tp1) do { \ 296270352Stuexen tp1->window_probe = 0; \ 297168709Srrs if (stcb->asoc.total_flight >= tp1->book_size) { \ 298168709Srrs stcb->asoc.total_flight -= tp1->book_size; \ 299168709Srrs if (stcb->asoc.total_flight_count > 0) \ 300168709Srrs stcb->asoc.total_flight_count--; \ 301168709Srrs } else { \ 302171440Srrs stcb->asoc.total_flight = 0; \ 303171440Srrs stcb->asoc.total_flight_count = 0; \ 304168709Srrs } \ 305168709Srrs} while (0) 306168709Srrs 307168709Srrs#define sctp_total_flight_increase(stcb, tp1) do { \ 308270352Stuexen (stcb)->asoc.total_flight_count++; \ 309270352Stuexen (stcb)->asoc.total_flight += (tp1)->book_size; \ 310168709Srrs} while (0) 311168709Srrs 312171440Srrs#endif 313171440Srrs 314224641Stuexen#define SCTP_PF_ENABLED(_net) (_net->pf_threshold < _net->failure_threshold) 315224641Stuexen#define SCTP_NET_IS_PF(_net) (_net->pf_threshold < _net->error_count) 316171943Srrs 317163953Srrsstruct sctp_nets; 318163953Srrsstruct sctp_inpcb; 319163953Srrsstruct sctp_tcb; 320163953Srrsstruct sctphdr; 321163953Srrs 322171990Srrs 323171990Srrsvoid sctp_close(struct socket *so); 324171990Srrsint sctp_disconnect(struct socket *so); 325241916Sdelphijvoid sctp_ctlinput(int, struct sockaddr *, void *); 326241916Sdelphijint sctp_ctloutput(struct socket *, struct sockopt *); 327221249Stuexen 328221249Stuexen#ifdef INET 329241916Sdelphijvoid sctp_input_with_port(struct mbuf *, int, uint16_t); 330241916Sdelphijvoid sctp_input(struct mbuf *, int); 331221249Stuexen 332221249Stuexen#endif 333241916Sdelphijvoid sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); 334241916Sdelphijvoid sctp_drain(void); 335241916Sdelphijvoid sctp_init(void); 336179783Srrsvoid sctp_finish(void); 337178202Srrsint sctp_flush(struct socket *, int); 338241916Sdelphijint sctp_shutdown(struct socket *); 339242327Stuexenvoid 340242327Stuexensctp_notify(struct sctp_inpcb *, struct ip *ip, struct sctphdr *, 341163953Srrs struct sockaddr *, struct sctp_tcb *, 342241916Sdelphij struct sctp_nets *); 343242327Stuexenint 344242327Stuexensctp_bindx(struct socket *, int, struct sockaddr_storage *, 345242327Stuexen int, int, struct proc *); 346163953Srrs 347163953Srrs/* can't use sctp_assoc_t here */ 348242327Stuexenint sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *); 349242327Stuexenint sctp_ingetaddr(struct socket *, struct sockaddr **); 350242327Stuexenint sctp_peeraddr(struct socket *, struct sockaddr **); 351242327Stuexenint sctp_listen(struct socket *, int, struct thread *); 352242327Stuexenint sctp_accept(struct socket *, struct sockaddr **); 353163953Srrs 354163953Srrs#endif /* _KERNEL */ 355163953Srrs 356163953Srrs#endif /* !_NETINET_SCTP_VAR_H_ */ 357