xref: /freebsd/sys/netinet/sctp_bsd_addr.c (revision a18eacbefdfa1085ca3db829e86ece78cd416493)
1 /*-
2  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4  * Copyright (c) 2008-2012, 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 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <netinet/sctp_os.h>
37 #include <netinet/sctp_var.h>
38 #include <netinet/sctp_pcb.h>
39 #include <netinet/sctp_header.h>
40 #include <netinet/sctputil.h>
41 #include <netinet/sctp_output.h>
42 #include <netinet/sctp_bsd_addr.h>
43 #include <netinet/sctp_uio.h>
44 #include <netinet/sctputil.h>
45 #include <netinet/sctp_timer.h>
46 #include <netinet/sctp_asconf.h>
47 #include <netinet/sctp_sysctl.h>
48 #include <netinet/sctp_indata.h>
49 #include <sys/unistd.h>
50 
51 /* Declare all of our malloc named types */
52 MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
53 MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
54 MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
55 MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address");
56 MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
57 MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist");
58 MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key");
59 MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list");
60 MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info");
61 MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset");
62 MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer");
63 MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all");
64 MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct");
65 MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct");
66 MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct");
67 MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block");
68 MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
69 MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
70 MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
71 MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue");
72 
73 /* Global NON-VNET structure that controls the iterator */
74 struct iterator_control sctp_it_ctl;
75 
76 
77 void
78 sctp_wakeup_iterator(void)
79 {
80 	wakeup(&sctp_it_ctl.iterator_running);
81 }
82 
83 static void
84 sctp_iterator_thread(void *v SCTP_UNUSED)
85 {
86 	SCTP_IPI_ITERATOR_WQ_LOCK();
87 	/* In FreeBSD this thread never terminates. */
88 	for (;;) {
89 		msleep(&sctp_it_ctl.iterator_running,
90 		    &sctp_it_ctl.ipi_iterator_wq_mtx,
91 		    0, "waiting_for_work", 0);
92 		sctp_iterator_worker();
93 	}
94 }
95 
96 void
97 sctp_startup_iterator(void)
98 {
99 	if (sctp_it_ctl.thread_proc) {
100 		/* You only get one */
101 		return;
102 	}
103 	TAILQ_INIT(&sctp_it_ctl.iteratorhead);
104 	kproc_create(sctp_iterator_thread,
105 	    (void *)NULL,
106 	    &sctp_it_ctl.thread_proc,
107 	    RFPROC,
108 	    SCTP_KTHREAD_PAGES,
109 	    SCTP_KTRHEAD_NAME);
110 }
111 
112 #ifdef INET6
113 
114 void
115 sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
116 {
117 	struct in6_ifaddr *ifa6;
118 
119 	ifa6 = (struct in6_ifaddr *)ifa->ifa;
120 	ifa->flags = ifa6->ia6_flags;
121 	if (!MODULE_GLOBAL(ip6_use_deprecated)) {
122 		if (ifa->flags &
123 		    IN6_IFF_DEPRECATED) {
124 			ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
125 		} else {
126 			ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
127 		}
128 	} else {
129 		ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
130 	}
131 	if (ifa->flags &
132 	    (IN6_IFF_DETACHED |
133 	    IN6_IFF_ANYCAST |
134 	    IN6_IFF_NOTREADY)) {
135 		ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
136 	} else {
137 		ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
138 	}
139 }
140 
141 #endif				/* INET6 */
142 
143 
144 static uint32_t
145 sctp_is_desired_interface_type(struct ifnet *ifn)
146 {
147 	int result;
148 
149 	/* check the interface type to see if it's one we care about */
150 	switch (ifn->if_type) {
151 	case IFT_ETHER:
152 	case IFT_ISO88023:
153 	case IFT_ISO88024:
154 	case IFT_ISO88025:
155 	case IFT_ISO88026:
156 	case IFT_STARLAN:
157 	case IFT_P10:
158 	case IFT_P80:
159 	case IFT_HY:
160 	case IFT_FDDI:
161 	case IFT_XETHER:
162 	case IFT_ISDNBASIC:
163 	case IFT_ISDNPRIMARY:
164 	case IFT_PTPSERIAL:
165 	case IFT_OTHER:
166 	case IFT_PPP:
167 	case IFT_LOOP:
168 	case IFT_SLIP:
169 	case IFT_GIF:
170 	case IFT_L2VLAN:
171 	case IFT_STF:
172 	case IFT_IP:
173 	case IFT_IPOVERCDLC:
174 	case IFT_IPOVERCLAW:
175 	case IFT_PROPVIRTUAL:	/* NetGraph Virtual too */
176 	case IFT_VIRTUALIPADDRESS:
177 		result = 1;
178 		break;
179 	default:
180 		result = 0;
181 	}
182 
183 	return (result);
184 }
185 
186 
187 
188 
189 static void
190 sctp_init_ifns_for_vrf(int vrfid)
191 {
192 	/*
193 	 * Here we must apply ANY locks needed by the IFN we access and also
194 	 * make sure we lock any IFA that exists as we float through the
195 	 * list of IFA's
196 	 */
197 	struct ifnet *ifn;
198 	struct ifaddr *ifa;
199 	struct sctp_ifa *sctp_ifa;
200 	uint32_t ifa_flags;
201 
202 #ifdef INET6
203 	struct in6_ifaddr *ifa6;
204 
205 #endif
206 
207 	IFNET_RLOCK();
208 	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
209 		if (sctp_is_desired_interface_type(ifn) == 0) {
210 			/* non desired type */
211 			continue;
212 		}
213 		IF_ADDR_RLOCK(ifn);
214 		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
215 			if (ifa->ifa_addr == NULL) {
216 				continue;
217 			}
218 			switch (ifa->ifa_addr->sa_family) {
219 #ifdef INET
220 			case AF_INET:
221 				if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
222 					continue;
223 				}
224 				break;
225 #endif
226 #ifdef INET6
227 			case AF_INET6:
228 				if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
229 					/* skip unspecifed addresses */
230 					continue;
231 				}
232 				break;
233 #endif
234 			default:
235 				continue;
236 			}
237 			switch (ifa->ifa_addr->sa_family) {
238 #ifdef INET
239 			case AF_INET:
240 				ifa_flags = 0;
241 				break;
242 #endif
243 #ifdef INET6
244 			case AF_INET6:
245 				ifa6 = (struct in6_ifaddr *)ifa;
246 				ifa_flags = ifa6->ia6_flags;
247 				break;
248 #endif
249 			default:
250 				ifa_flags = 0;
251 				break;
252 			}
253 			sctp_ifa = sctp_add_addr_to_vrf(vrfid,
254 			    (void *)ifn,
255 			    ifn->if_index,
256 			    ifn->if_type,
257 			    ifn->if_xname,
258 			    (void *)ifa,
259 			    ifa->ifa_addr,
260 			    ifa_flags,
261 			    0);
262 			if (sctp_ifa) {
263 				sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
264 			}
265 		}
266 		IF_ADDR_RUNLOCK(ifn);
267 	}
268 	IFNET_RUNLOCK();
269 }
270 
271 void
272 sctp_init_vrf_list(int vrfid)
273 {
274 	if (vrfid > SCTP_MAX_VRF_ID)
275 		/* can't do that */
276 		return;
277 
278 	/* Don't care about return here */
279 	(void)sctp_allocate_vrf(vrfid);
280 
281 	/*
282 	 * Now we need to build all the ifn's for this vrf and there
283 	 * addresses
284 	 */
285 	sctp_init_ifns_for_vrf(vrfid);
286 }
287 
288 void
289 sctp_addr_change(struct ifaddr *ifa, int cmd)
290 {
291 	uint32_t ifa_flags = 0;
292 
293 	/*
294 	 * BSD only has one VRF, if this changes we will need to hook in the
295 	 * right things here to get the id to pass to the address managment
296 	 * routine.
297 	 */
298 	if (SCTP_BASE_VAR(first_time) == 0) {
299 		/* Special test to see if my ::1 will showup with this */
300 		SCTP_BASE_VAR(first_time) = 1;
301 		sctp_init_ifns_for_vrf(SCTP_DEFAULT_VRFID);
302 	}
303 	if ((cmd != RTM_ADD) && (cmd != RTM_DELETE)) {
304 		/* don't know what to do with this */
305 		return;
306 	}
307 	if (ifa->ifa_addr == NULL) {
308 		return;
309 	}
310 	if (sctp_is_desired_interface_type(ifa->ifa_ifp) == 0) {
311 		/* non desired type */
312 		return;
313 	}
314 	switch (ifa->ifa_addr->sa_family) {
315 #ifdef INET
316 	case AF_INET:
317 		if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
318 			return;
319 		}
320 		break;
321 #endif
322 #ifdef INET6
323 	case AF_INET6:
324 		ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
325 		if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
326 			/* skip unspecifed addresses */
327 			return;
328 		}
329 		break;
330 #endif
331 	default:
332 		/* non inet/inet6 skip */
333 		return;
334 	}
335 	if (cmd == RTM_ADD) {
336 		(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp,
337 		    ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname,
338 		    (void *)ifa, ifa->ifa_addr, ifa_flags, 1);
339 	} else {
340 
341 		sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
342 		    ifa->ifa_ifp->if_index,
343 		    ifa->ifa_ifp->if_xname);
344 
345 		/*
346 		 * We don't bump refcount here so when it completes the
347 		 * final delete will happen.
348 		 */
349 	}
350 }
351 
352 void
353      sctp_add_or_del_interfaces(int (*pred) (struct ifnet *), int add){
354 	struct ifnet *ifn;
355 	struct ifaddr *ifa;
356 
357 	IFNET_RLOCK();
358 	TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
359 		if (!(*pred) (ifn)) {
360 			continue;
361 		}
362 		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
363 			sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
364 		}
365 	}
366 	IFNET_RUNLOCK();
367 }
368 
369 struct mbuf *
370 sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
371     int how, int allonebuf, int type)
372 {
373 	struct mbuf *m = NULL;
374 
375 	m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
376 	if (m == NULL) {
377 		/* bad, no memory */
378 		return (m);
379 	}
380 	if (allonebuf) {
381 		int siz;
382 
383 		if (SCTP_BUF_IS_EXTENDED(m)) {
384 			siz = SCTP_BUF_EXTEND_SIZE(m);
385 		} else {
386 			if (want_header)
387 				siz = MHLEN;
388 			else
389 				siz = MLEN;
390 		}
391 		if (siz < space_needed) {
392 			m_freem(m);
393 			return (NULL);
394 		}
395 	}
396 	if (SCTP_BUF_NEXT(m)) {
397 		sctp_m_freem(SCTP_BUF_NEXT(m));
398 		SCTP_BUF_NEXT(m) = NULL;
399 	}
400 #ifdef SCTP_MBUF_LOGGING
401 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
402 		if (SCTP_BUF_IS_EXTENDED(m)) {
403 			sctp_log_mb(m, SCTP_MBUF_IALLOC);
404 		}
405 	}
406 #endif
407 	return (m);
408 }
409 
410 
411 #ifdef SCTP_PACKET_LOGGING
412 void
413 sctp_packet_log(struct mbuf *m)
414 {
415 	int *lenat, thisone;
416 	void *copyto;
417 	uint32_t *tick_tock;
418 	int length;
419 	int total_len;
420 	int grabbed_lock = 0;
421 	int value, newval, thisend, thisbegin;
422 
423 	/*
424 	 * Buffer layout. -sizeof this entry (total_len) -previous end
425 	 * (value) -ticks of log      (ticks) o -ip packet o -as logged -
426 	 * where this started (thisbegin) x <--end points here
427 	 */
428 	length = SCTP_HEADER_LEN(m);
429 	total_len = SCTP_SIZE32((length + (4 * sizeof(int))));
430 	/* Log a packet to the buffer. */
431 	if (total_len > SCTP_PACKET_LOG_SIZE) {
432 		/* Can't log this packet I have not a buffer big enough */
433 		return;
434 	}
435 	if (length < (int)(SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
436 		return;
437 	}
438 	atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), 1);
439 try_again:
440 	if (SCTP_BASE_VAR(packet_log_writers) > SCTP_PKTLOG_WRITERS_NEED_LOCK) {
441 		SCTP_IP_PKTLOG_LOCK();
442 		grabbed_lock = 1;
443 again_locked:
444 		value = SCTP_BASE_VAR(packet_log_end);
445 		newval = SCTP_BASE_VAR(packet_log_end) + total_len;
446 		if (newval >= SCTP_PACKET_LOG_SIZE) {
447 			/* we wrapped */
448 			thisbegin = 0;
449 			thisend = total_len;
450 		} else {
451 			thisbegin = SCTP_BASE_VAR(packet_log_end);
452 			thisend = newval;
453 		}
454 		if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
455 			goto again_locked;
456 		}
457 	} else {
458 		value = SCTP_BASE_VAR(packet_log_end);
459 		newval = SCTP_BASE_VAR(packet_log_end) + total_len;
460 		if (newval >= SCTP_PACKET_LOG_SIZE) {
461 			/* we wrapped */
462 			thisbegin = 0;
463 			thisend = total_len;
464 		} else {
465 			thisbegin = SCTP_BASE_VAR(packet_log_end);
466 			thisend = newval;
467 		}
468 		if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
469 			goto try_again;
470 		}
471 	}
472 	/* Sanity check */
473 	if (thisend >= SCTP_PACKET_LOG_SIZE) {
474 		SCTP_PRINTF("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n",
475 		    thisbegin,
476 		    thisend,
477 		    SCTP_BASE_VAR(packet_log_writers),
478 		    grabbed_lock,
479 		    SCTP_BASE_VAR(packet_log_end));
480 		SCTP_BASE_VAR(packet_log_end) = 0;
481 		goto no_log;
482 
483 	}
484 	lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
485 	*lenat = total_len;
486 	lenat++;
487 	*lenat = value;
488 	lenat++;
489 	tick_tock = (uint32_t *) lenat;
490 	lenat++;
491 	*tick_tock = sctp_get_tick_count();
492 	copyto = (void *)lenat;
493 	thisone = thisend - sizeof(int);
494 	lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisone];
495 	*lenat = thisbegin;
496 	if (grabbed_lock) {
497 		SCTP_IP_PKTLOG_UNLOCK();
498 		grabbed_lock = 0;
499 	}
500 	m_copydata(m, 0, length, (caddr_t)copyto);
501 no_log:
502 	if (grabbed_lock) {
503 		SCTP_IP_PKTLOG_UNLOCK();
504 	}
505 	atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
506 }
507 
508 
509 int
510 sctp_copy_out_packet_log(uint8_t * target, int length)
511 {
512 	/*
513 	 * We wind through the packet log starting at start copying up to
514 	 * length bytes out. We return the number of bytes copied.
515 	 */
516 	int tocopy, this_copy;
517 	int *lenat;
518 	int did_delay = 0;
519 
520 	tocopy = length;
521 	if (length < (int)(2 * sizeof(int))) {
522 		/* not enough room */
523 		return (0);
524 	}
525 	if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
526 		atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), SCTP_PKTLOG_WRITERS_NEED_LOCK);
527 again:
528 		if ((did_delay == 0) && (SCTP_BASE_VAR(packet_log_writers) != SCTP_PKTLOG_WRITERS_NEED_LOCK)) {
529 			/*
530 			 * we delay here for just a moment hoping the
531 			 * writer(s) that were present when we entered will
532 			 * have left and we only have locking ones that will
533 			 * contend with us for the lock. This does not
534 			 * assure 100% access, but its good enough for a
535 			 * logging facility like this.
536 			 */
537 			did_delay = 1;
538 			DELAY(10);
539 			goto again;
540 		}
541 	}
542 	SCTP_IP_PKTLOG_LOCK();
543 	lenat = (int *)target;
544 	*lenat = SCTP_BASE_VAR(packet_log_end);
545 	lenat++;
546 	this_copy = min((length - sizeof(int)), SCTP_PACKET_LOG_SIZE);
547 	memcpy((void *)lenat, (void *)SCTP_BASE_VAR(packet_log_buffer), this_copy);
548 	if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
549 		atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers),
550 		    SCTP_PKTLOG_WRITERS_NEED_LOCK);
551 	}
552 	SCTP_IP_PKTLOG_UNLOCK();
553 	return (this_copy + sizeof(int));
554 }
555 
556 #endif
557