PageRenderTime 213ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/sys/netinet/sctp_var.h

https://github.com/okuoku/freebsd-head
C Header | 370 lines | 272 code | 55 blank | 43 comment | 76 complexity | 3777f27eb797ac20b012afc61f2a867f MD5 | raw file
  1. /*-
  2. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
  3. * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
  4. * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * a) Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. *
  12. * b) Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the distribution.
  15. *
  16. * c) Neither the name of Cisco Systems, Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  24. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  30. * THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. /* $KAME: sctp_var.h,v 1.24 2005/03/06 16:04:19 itojun Exp $ */
  33. #include <sys/cdefs.h>
  34. __FBSDID("$FreeBSD$");
  35. #ifndef _NETINET_SCTP_VAR_H_
  36. #define _NETINET_SCTP_VAR_H_
  37. #include <netinet/sctp_uio.h>
  38. #if defined(_KERNEL) || defined(__Userspace__)
  39. extern struct pr_usrreqs sctp_usrreqs;
  40. #define sctp_feature_on(inp, feature) (inp->sctp_features |= feature)
  41. #define sctp_feature_off(inp, feature) (inp->sctp_features &= ~feature)
  42. #define sctp_is_feature_on(inp, feature) ((inp->sctp_features & feature) == feature)
  43. #define sctp_is_feature_off(inp, feature) ((inp->sctp_features & feature) == 0)
  44. #define sctp_stcb_feature_on(inp, stcb, feature) {\
  45. if (stcb) { \
  46. stcb->asoc.sctp_features |= feature; \
  47. } else { \
  48. inp->sctp_features |= feature; \
  49. } \
  50. }
  51. #define sctp_stcb_feature_off(inp, stcb, feature) {\
  52. if (stcb) { \
  53. stcb->asoc.sctp_features &= ~feature; \
  54. } else { \
  55. inp->sctp_features &= ~feature; \
  56. } \
  57. }
  58. #define sctp_stcb_is_feature_on(inp, stcb, feature) \
  59. (((stcb != NULL) && \
  60. ((stcb->asoc.sctp_features & feature) == feature)) || \
  61. ((stcb == NULL) && \
  62. ((inp->sctp_features & feature) == feature)))
  63. #define sctp_stcb_is_feature_off(inp, stcb, feature) \
  64. (((stcb != NULL) && \
  65. ((stcb->asoc.sctp_features & feature) == 0)) || \
  66. ((stcb == NULL) && \
  67. ((inp->sctp_features & feature) == 0)))
  68. /* managing mobility_feature in inpcb (by micchie) */
  69. #define sctp_mobility_feature_on(inp, feature) (inp->sctp_mobility_features |= feature)
  70. #define sctp_mobility_feature_off(inp, feature) (inp->sctp_mobility_features &= ~feature)
  71. #define sctp_is_mobility_feature_on(inp, feature) (inp->sctp_mobility_features & feature)
  72. #define sctp_is_mobility_feature_off(inp, feature) ((inp->sctp_mobility_features & feature) == 0)
  73. #define sctp_maxspace(sb) (max((sb)->sb_hiwat,SCTP_MINIMAL_RWND))
  74. #define sctp_sbspace(asoc, sb) ((long) ((sctp_maxspace(sb) > (asoc)->sb_cc) ? (sctp_maxspace(sb) - (asoc)->sb_cc) : 0))
  75. #define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0))
  76. #define sctp_sbspace_sub(a,b) ((a > b) ? (a - b) : 0)
  77. /*
  78. * I tried to cache the readq entries at one point. But the reality
  79. * is that it did not add any performance since this meant we had to
  80. * lock the STCB on read. And at that point once you have to do an
  81. * extra lock, it really does not matter if the lock is in the ZONE
  82. * stuff or in our code. Note that this same problem would occur with
  83. * an mbuf cache as well so it is not really worth doing, at least
  84. * right now :-D
  85. */
  86. #define sctp_free_a_readq(_stcb, _readq) { \
  87. SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), (_readq)); \
  88. SCTP_DECR_READQ_COUNT(); \
  89. }
  90. #define sctp_alloc_a_readq(_stcb, _readq) { \
  91. (_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \
  92. if ((_readq)) { \
  93. SCTP_INCR_READQ_COUNT(); \
  94. } \
  95. }
  96. #define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked) { \
  97. if ((_strmoq)->holds_key_ref) { \
  98. sctp_auth_key_release(stcb, sp->auth_keyid, _so_locked); \
  99. (_strmoq)->holds_key_ref = 0; \
  100. } \
  101. SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), (_strmoq)); \
  102. SCTP_DECR_STRMOQ_COUNT(); \
  103. }
  104. #define sctp_alloc_a_strmoq(_stcb, _strmoq) { \
  105. (_strmoq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_strmoq), struct sctp_stream_queue_pending); \
  106. if ((_strmoq)) { \
  107. memset(_strmoq, 0, sizeof(struct sctp_stream_queue_pending)); \
  108. SCTP_INCR_STRMOQ_COUNT(); \
  109. (_strmoq)->holds_key_ref = 0; \
  110. } \
  111. }
  112. #define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \
  113. if ((_chk)->holds_key_ref) {\
  114. sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \
  115. (_chk)->holds_key_ref = 0; \
  116. } \
  117. if (_stcb) { \
  118. SCTP_TCB_LOCK_ASSERT((_stcb)); \
  119. if ((_chk)->whoTo) { \
  120. sctp_free_remote_addr((_chk)->whoTo); \
  121. (_chk)->whoTo = NULL; \
  122. } \
  123. if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \
  124. (SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \
  125. SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
  126. SCTP_DECR_CHK_COUNT(); \
  127. } else { \
  128. TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
  129. (_stcb)->asoc.free_chunk_cnt++; \
  130. atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
  131. } \
  132. } else { \
  133. SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
  134. SCTP_DECR_CHK_COUNT(); \
  135. } \
  136. }
  137. #define sctp_alloc_a_chunk(_stcb, _chk) { \
  138. if (TAILQ_EMPTY(&(_stcb)->asoc.free_chunks)) { \
  139. (_chk) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_chunk), struct sctp_tmit_chunk); \
  140. if ((_chk)) { \
  141. SCTP_INCR_CHK_COUNT(); \
  142. (_chk)->whoTo = NULL; \
  143. (_chk)->holds_key_ref = 0; \
  144. } \
  145. } else { \
  146. (_chk) = TAILQ_FIRST(&(_stcb)->asoc.free_chunks); \
  147. TAILQ_REMOVE(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
  148. atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
  149. (_chk)->holds_key_ref = 0; \
  150. SCTP_STAT_INCR(sctps_cached_chk); \
  151. (_stcb)->asoc.free_chunk_cnt--; \
  152. } \
  153. }
  154. #define sctp_free_remote_addr(__net) { \
  155. if ((__net)) { \
  156. if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
  157. (void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
  158. (void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
  159. if ((__net)->ro.ro_rt) { \
  160. RTFREE((__net)->ro.ro_rt); \
  161. (__net)->ro.ro_rt = NULL; \
  162. } \
  163. if ((__net)->src_addr_selected) { \
  164. sctp_free_ifa((__net)->ro._s_addr); \
  165. (__net)->ro._s_addr = NULL; \
  166. } \
  167. (__net)->src_addr_selected = 0; \
  168. (__net)->dest_state &= ~SCTP_ADDR_REACHABLE; \
  169. SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \
  170. SCTP_DECR_RADDR_COUNT(); \
  171. } \
  172. } \
  173. }
  174. #define sctp_sbfree(ctl, stcb, sb, m) { \
  175. SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \
  176. SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \
  177. if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
  178. SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \
  179. SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \
  180. } \
  181. if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
  182. SCTP_BUF_TYPE(m) != MT_OOBDATA) \
  183. atomic_subtract_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
  184. }
  185. #define sctp_sballoc(stcb, sb, m) { \
  186. atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
  187. atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
  188. if (stcb) { \
  189. atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \
  190. atomic_add_int(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \
  191. } \
  192. if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
  193. SCTP_BUF_TYPE(m) != MT_OOBDATA) \
  194. atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
  195. }
  196. #define sctp_ucount_incr(val) { \
  197. val++; \
  198. }
  199. #define sctp_ucount_decr(val) { \
  200. if (val > 0) { \
  201. val--; \
  202. } else { \
  203. val = 0; \
  204. } \
  205. }
  206. #define sctp_mbuf_crush(data) do { \
  207. struct mbuf *_m; \
  208. _m = (data); \
  209. while(_m && (SCTP_BUF_LEN(_m) == 0)) { \
  210. (data) = SCTP_BUF_NEXT(_m); \
  211. SCTP_BUF_NEXT(_m) = NULL; \
  212. sctp_m_free(_m); \
  213. _m = (data); \
  214. } \
  215. } while (0)
  216. #define sctp_flight_size_decrease(tp1) do { \
  217. if (tp1->whoTo->flight_size >= tp1->book_size) \
  218. tp1->whoTo->flight_size -= tp1->book_size; \
  219. else \
  220. tp1->whoTo->flight_size = 0; \
  221. } while (0)
  222. #define sctp_flight_size_increase(tp1) do { \
  223. (tp1)->whoTo->flight_size += (tp1)->book_size; \
  224. } while (0)
  225. #ifdef SCTP_FS_SPEC_LOG
  226. #define sctp_total_flight_decrease(stcb, tp1) do { \
  227. if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
  228. stcb->asoc.fs_index = 0;\
  229. stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
  230. stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
  231. stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
  232. stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
  233. stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
  234. stcb->asoc.fslog[stcb->asoc.fs_index].decr = 1; \
  235. stcb->asoc.fs_index++; \
  236. tp1->window_probe = 0; \
  237. if (stcb->asoc.total_flight >= tp1->book_size) { \
  238. stcb->asoc.total_flight -= tp1->book_size; \
  239. if (stcb->asoc.total_flight_count > 0) \
  240. stcb->asoc.total_flight_count--; \
  241. } else { \
  242. stcb->asoc.total_flight = 0; \
  243. stcb->asoc.total_flight_count = 0; \
  244. } \
  245. } while (0)
  246. #define sctp_total_flight_increase(stcb, tp1) do { \
  247. if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
  248. stcb->asoc.fs_index = 0;\
  249. stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
  250. stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
  251. stcb->asoc.fslog[stcb->asoc.fs_index].book = tp1->book_size; \
  252. stcb->asoc.fslog[stcb->asoc.fs_index].sent = tp1->sent; \
  253. stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
  254. stcb->asoc.fslog[stcb->asoc.fs_index].decr = 0; \
  255. stcb->asoc.fs_index++; \
  256. (stcb)->asoc.total_flight_count++; \
  257. (stcb)->asoc.total_flight += (tp1)->book_size; \
  258. } while (0)
  259. #else
  260. #define sctp_total_flight_decrease(stcb, tp1) do { \
  261. tp1->window_probe = 0; \
  262. if (stcb->asoc.total_flight >= tp1->book_size) { \
  263. stcb->asoc.total_flight -= tp1->book_size; \
  264. if (stcb->asoc.total_flight_count > 0) \
  265. stcb->asoc.total_flight_count--; \
  266. } else { \
  267. stcb->asoc.total_flight = 0; \
  268. stcb->asoc.total_flight_count = 0; \
  269. } \
  270. } while (0)
  271. #define sctp_total_flight_increase(stcb, tp1) do { \
  272. (stcb)->asoc.total_flight_count++; \
  273. (stcb)->asoc.total_flight += (tp1)->book_size; \
  274. } while (0)
  275. #endif
  276. #define SCTP_PF_ENABLED(_net) (_net->pf_threshold < _net->failure_threshold)
  277. #define SCTP_NET_IS_PF(_net) (_net->pf_threshold < _net->error_count)
  278. struct sctp_nets;
  279. struct sctp_inpcb;
  280. struct sctp_tcb;
  281. struct sctphdr;
  282. void sctp_close(struct socket *so);
  283. int sctp_disconnect(struct socket *so);
  284. void sctp_ctlinput __P((int, struct sockaddr *, void *));
  285. int sctp_ctloutput __P((struct socket *, struct sockopt *));
  286. #ifdef INET
  287. void sctp_input_with_port __P((struct mbuf *, int, uint16_t));
  288. #endif
  289. #ifdef INET
  290. void sctp_input __P((struct mbuf *, int));
  291. #endif
  292. void sctp_pathmtu_adjustment __P((struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *, uint16_t));
  293. void sctp_drain __P((void));
  294. void sctp_init __P((void));
  295. void sctp_finish(void);
  296. int sctp_flush(struct socket *, int);
  297. int sctp_shutdown __P((struct socket *));
  298. void sctp_notify
  299. __P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
  300. struct sockaddr *, struct sctp_tcb *,
  301. struct sctp_nets *));
  302. int sctp_bindx(struct socket *, int, struct sockaddr_storage *,
  303. int, int, struct proc *);
  304. /* can't use sctp_assoc_t here */
  305. int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
  306. int sctp_ingetaddr(struct socket *,
  307. struct sockaddr **
  308. );
  309. int sctp_peeraddr(struct socket *,
  310. struct sockaddr **
  311. );
  312. int sctp_listen(struct socket *, int, struct thread *);
  313. int sctp_accept(struct socket *, struct sockaddr **);
  314. #endif /* _KERNEL */
  315. #endif /* !_NETINET_SCTP_VAR_H_ */