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