1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * a) Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * b) Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the distribution.
17 *
18 * c) Neither the name of Cisco Systems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #ifdef __FreeBSD__
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 353480 2019-10-13 18:17:08Z tuexen $");
38 #endif
39
40 #include <netinet/sctp_os.h>
41 #include <netinet/sctp_var.h>
42 #include <netinet/sctp_pcb.h>
43 #include <netinet/sctp_header.h>
44 #include <netinet/sctputil.h>
45 #include <netinet/sctp_output.h>
46 #include <netinet/sctp_bsd_addr.h>
47 #include <netinet/sctp_uio.h>
48 #include <netinet/sctputil.h>
49 #include <netinet/sctp_timer.h>
50 #include <netinet/sctp_asconf.h>
51 #include <netinet/sctp_sysctl.h>
52 #include <netinet/sctp_indata.h>
53 #if defined(__FreeBSD__)
54 #include <sys/unistd.h>
55 #endif
56
57 /* Declare all of our malloc named types */
58 #ifndef __Panda__
59 MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
60 MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
61 MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
62 MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address");
63 MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
64 MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist");
65 MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key");
66 MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list");
67 MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info");
68 MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset");
69 MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer");
70 MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all");
71 MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct");
72 MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct");
73 MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct");
74 MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block");
75 MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
76 MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
77 MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
78 MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue");
79 #endif
80
81 /* Global NON-VNET structure that controls the iterator */
82 struct iterator_control sctp_it_ctl;
83
84 #if !defined(__FreeBSD__)
85 static void
sctp_cleanup_itqueue(void)86 sctp_cleanup_itqueue(void)
87 {
88 struct sctp_iterator *it, *nit;
89
90 TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
91 if (it->function_atend != NULL) {
92 (*it->function_atend) (it->pointer, it->val);
93 }
94 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
95 SCTP_FREE(it, SCTP_M_ITER);
96 }
97 }
98 #endif
99 #if defined(__Userspace__)
100 /*__Userspace__ TODO if we use thread based iterator
101 * then the implementation of wakeup will need to change.
102 * Currently we are using timeo_cond for ident so_timeo
103 * but that is not sufficient if we need to use another ident
104 * like wakeup(&sctppcbinfo.iterator_running);
105 */
106 #endif
107
108 void
sctp_wakeup_iterator(void)109 sctp_wakeup_iterator(void)
110 {
111 #if defined(SCTP_PROCESS_LEVEL_LOCKS)
112 #if defined(__Userspace_os_Windows)
113 WakeAllConditionVariable(&sctp_it_ctl.iterator_wakeup);
114 #else
115 pthread_cond_broadcast(&sctp_it_ctl.iterator_wakeup);
116 #endif
117 #else
118 wakeup(&sctp_it_ctl.iterator_running);
119 #endif
120 }
121
122 #if defined(__Userspace__)
123 static void *
124 #else
125 static void
126 #endif
sctp_iterator_thread(void * v SCTP_UNUSED)127 sctp_iterator_thread(void *v SCTP_UNUSED)
128 {
129 #if defined(__Userspace__)
130 sctp_userspace_set_threadname("SCTP iterator");
131 #endif
132 SCTP_IPI_ITERATOR_WQ_LOCK();
133 /* In FreeBSD this thread never terminates. */
134 #if defined(__FreeBSD__)
135 for (;;) {
136 #else
137 while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) == 0) {
138 #endif
139 #if !defined(__Userspace__)
140 msleep(&sctp_it_ctl.iterator_running,
141 #if defined(__FreeBSD__)
142 &sctp_it_ctl.ipi_iterator_wq_mtx,
143 #elif defined(__APPLE__) || defined(__Userspace_os_Darwin)
144 sctp_it_ctl.ipi_iterator_wq_mtx,
145 #endif
146 0, "waiting_for_work", 0);
147 #else
148 #if defined(__Userspace_os_Windows)
149 SleepConditionVariableCS(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx, INFINITE);
150 #else
151 pthread_cond_wait(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx);
152 #endif
153 #endif
154 #if !defined(__FreeBSD__)
155 if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
156 break;
157 }
158 #endif
159 sctp_iterator_worker();
160 }
161 #if !defined(__FreeBSD__)
162 /* Now this thread needs to be terminated */
163 sctp_cleanup_itqueue();
164 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_EXITED;
165 SCTP_IPI_ITERATOR_WQ_UNLOCK();
166 #if defined(__Userspace__)
167 sctp_wakeup_iterator();
168 return (NULL);
169 #else
170 wakeup(&sctp_it_ctl.iterator_flags);
171 thread_terminate(current_thread());
172 #ifdef INVARIANTS
173 panic("Hmm. thread_terminate() continues...");
174 #endif
175 #endif
176 #endif
177 }
178
179 void
180 sctp_startup_iterator(void)
181 {
182 if (sctp_it_ctl.thread_proc) {
183 /* You only get one */
184 return;
185 }
186 /* Initialize global locks here, thus only once. */
187 SCTP_ITERATOR_LOCK_INIT();
188 SCTP_IPI_ITERATOR_WQ_INIT();
189 TAILQ_INIT(&sctp_it_ctl.iteratorhead);
190 #if defined(__FreeBSD__)
191 #if __FreeBSD_version <= 701000
192 kthread_create(sctp_iterator_thread,
193 #else
194 kproc_create(sctp_iterator_thread,
195 #endif
196 (void *)NULL,
197 &sctp_it_ctl.thread_proc,
198 RFPROC,
199 SCTP_KTHREAD_PAGES,
200 SCTP_KTRHEAD_NAME);
201 #elif defined(__APPLE__)
202 kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
203 #elif defined(__Userspace__)
204 if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) {
205 SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
206 }
207 #endif
208 }
209
210 #ifdef INET6
211
212 #if defined(__Userspace__)
213 /* __Userspace__ TODO. struct in6_ifaddr is defined in sys/netinet6/in6_var.h
214 ip6_use_deprecated is defined as int ip6_use_deprecated = 1; in /src/sys/netinet6/in6_proto.c
215 */
216 void
217 sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
218 {
219 return; /* stub */
220 }
221 #else
222 void
223 sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
224 {
225 struct in6_ifaddr *ifa6;
226
227 ifa6 = (struct in6_ifaddr *)ifa->ifa;
228 ifa->flags = ifa6->ia6_flags;
229 if (!MODULE_GLOBAL(ip6_use_deprecated)) {
230 if (ifa->flags &
231 IN6_IFF_DEPRECATED) {
232 ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
233 } else {
234 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
235 }
236 } else {
237 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
238 }
239 if (ifa->flags &
240 (IN6_IFF_DETACHED |
241 IN6_IFF_ANYCAST |
242 IN6_IFF_NOTREADY)) {
243 ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
244 } else {
245 ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
246 }
247 }
248 #endif /* __Userspace__ */
249 #endif /* INET6 */
250
251
252 #if !defined(__Userspace__)
253 static uint32_t
254 sctp_is_desired_interface_type(struct ifnet *ifn)
255 {
256 int result;
257
258 /* check the interface type to see if it's one we care about */
259 #if defined(__APPLE__)
260 switch(ifnet_type(ifn)) {
261 #else
262 switch (ifn->if_type) {
263 #endif
264 case IFT_ETHER:
265 case IFT_ISO88023:
266 case IFT_ISO88024:
267 case IFT_ISO88025:
268 case IFT_ISO88026:
269 case IFT_STARLAN:
270 case IFT_P10:
271 case IFT_P80:
272 case IFT_HY:
273 case IFT_FDDI:
274 case IFT_XETHER:
275 case IFT_ISDNBASIC:
276 case IFT_ISDNPRIMARY:
277 case IFT_PTPSERIAL:
278 case IFT_OTHER:
279 case IFT_PPP:
280 case IFT_LOOP:
281 case IFT_SLIP:
282 case IFT_GIF:
283 case IFT_L2VLAN:
284 case IFT_STF:
285 #if !defined(__APPLE__)
286 case IFT_IP:
287 case IFT_IPOVERCDLC:
288 case IFT_IPOVERCLAW:
289 case IFT_PROPVIRTUAL: /* NetGraph Virtual too */
290 case IFT_VIRTUALIPADDRESS:
291 #endif
292 result = 1;
293 break;
294 default:
295 result = 0;
296 }
297
298 return (result);
299 }
300 #endif
301
302 #if defined(__APPLE__)
303 int
304 sctp_is_vmware_interface(struct ifnet *ifn)
305 {
306 return (strncmp(ifnet_name(ifn), "vmnet", 5) == 0);
307 }
308 #endif
309
310 #if defined(__Userspace_os_Windows)
311 #ifdef MALLOC
312 #undef MALLOC
313 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
314 #endif
315 #ifdef FREE
316 #undef FREE
317 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
318 #endif
319 static void
320 sctp_init_ifns_for_vrf(int vrfid)
321 {
322 #if defined(INET) || defined(INET6)
323 struct sctp_ifa *sctp_ifa;
324 DWORD Err, AdapterAddrsSize;
325 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
326 PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
327 #endif
328
329 #ifdef INET
330 AdapterAddrsSize = 0;
331
332 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
333 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
334 SCTP_PRINTF("GetAdaptersV4Addresses() sizing failed with error code %d\n", Err);
335 SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
336 return;
337 }
338 }
339
340 /* Allocate memory from sizing information */
341 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
342 SCTP_PRINTF("Memory allocation error!\n");
343 return;
344 }
345 /* Get actual adapter information */
346 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
347 SCTP_PRINTF("GetAdaptersV4Addresses() failed with error code %d\n", Err);
348 FREE(pAdapterAddrs);
349 return;
350 }
351 /* Enumerate through each returned adapter and save its information */
352 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
353 if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
354 for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
355 if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
356 continue;
357 }
358 sctp_ifa = sctp_add_addr_to_vrf(0,
359 NULL,
360 pAdapt->IfIndex,
361 (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
362 pAdapt->AdapterName,
363 NULL,
364 pUnicast->Address.lpSockaddr,
365 pAdapt->Flags,
366 0);
367 if (sctp_ifa) {
368 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
369 }
370 }
371 }
372 }
373 FREE(pAdapterAddrs);
374 #endif
375 #ifdef INET6
376 AdapterAddrsSize = 0;
377
378 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
379 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
380 SCTP_PRINTF("GetAdaptersV6Addresses() sizing failed with error code %d\n", Err);
381 SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
382 return;
383 }
384 }
385 /* Allocate memory from sizing information */
386 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
387 SCTP_PRINTF("Memory allocation error!\n");
388 return;
389 }
390 /* Get actual adapter information */
391 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
392 SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
393 FREE(pAdapterAddrs);
394 return;
395 }
396 /* Enumerate through each returned adapter and save its information */
397 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
398 if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
399 for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
400 sctp_ifa = sctp_add_addr_to_vrf(0,
401 NULL,
402 pAdapt->Ipv6IfIndex,
403 (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
404 pAdapt->AdapterName,
405 NULL,
406 pUnicast->Address.lpSockaddr,
407 pAdapt->Flags,
408 0);
409 if (sctp_ifa) {
410 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
411 }
412 }
413 }
414 }
415 FREE(pAdapterAddrs);
416 #endif
417 }
418 #elif defined(__Userspace__)
419 static void
420 sctp_init_ifns_for_vrf(int vrfid)
421 {
422 #if defined(INET) || defined(INET6)
423 int rc;
424 struct ifaddrs *ifa, *ifas;
425 struct sctp_ifa *sctp_ifa;
426 uint32_t ifa_flags;
427
428 rc = getifaddrs(&ifas);
429 if (rc != 0) {
430 return;
431 }
432 for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
433 if (ifa->ifa_addr == NULL) {
434 continue;
435 }
436 #if !defined(INET)
437 if (ifa->ifa_addr->sa_family != AF_INET6) {
438 /* non inet6 skip */
439 continue;
440 }
441 #elif !defined(INET6)
442 if (ifa->ifa_addr->sa_family != AF_INET) {
443 /* non inet skip */
444 continue;
445 }
446 #else
447 if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
448 /* non inet/inet6 skip */
449 continue;
450 }
451 #endif
452 #if defined(INET6)
453 if ((ifa->ifa_addr->sa_family == AF_INET6) &&
454 IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
455 /* skip unspecifed addresses */
456 continue;
457 }
458 #endif
459 #if defined(INET)
460 if (ifa->ifa_addr->sa_family == AF_INET &&
461 ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
462 continue;
463 }
464 #endif
465 ifa_flags = 0;
466 sctp_ifa = sctp_add_addr_to_vrf(vrfid,
467 NULL,
468 if_nametoindex(ifa->ifa_name),
469 0,
470 ifa->ifa_name,
471 NULL,
472 ifa->ifa_addr,
473 ifa_flags,
474 0);
475 if (sctp_ifa) {
476 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
477 }
478 }
479 freeifaddrs(ifas);
480 #endif
481 }
482 #endif
483
484 #if defined(__APPLE__)
485 static void
486 sctp_init_ifns_for_vrf(int vrfid)
487 {
488 /* Here we must apply ANY locks needed by the
489 * IFN we access and also make sure we lock
490 * any IFA that exists as we float through the
491 * list of IFA's
492 */
493 struct ifnet **ifnetlist;
494 uint32_t i, j, count;
495 char name[SCTP_IFNAMSIZ];
496 struct ifnet *ifn;
497 struct ifaddr **ifaddrlist;
498 struct ifaddr *ifa;
499 struct in6_ifaddr *ifa6;
500 struct sctp_ifa *sctp_ifa;
501 uint32_t ifa_flags;
502
503 if (ifnet_list_get(IFNET_FAMILY_ANY, &ifnetlist, &count) != 0) {
504 return;
505 }
506 for (i = 0; i < count; i++) {
507 ifn = ifnetlist[i];
508 if (SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces) && sctp_is_vmware_interface(ifn)) {
509 continue;
510 }
511 if (sctp_is_desired_interface_type(ifn) == 0) {
512 /* non desired type */
513 continue;
514 }
515 if (ifnet_get_address_list(ifn, &ifaddrlist) != 0) {
516 continue;
517 }
518 for (j = 0; ifaddrlist[j] != NULL; j++) {
519 ifa = ifaddrlist[j];
520 if (ifa->ifa_addr == NULL) {
521 continue;
522 }
523 if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
524 /* non inet/inet6 skip */
525 continue;
526 }
527 if (ifa->ifa_addr->sa_family == AF_INET6) {
528 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
529 /* skip unspecifed addresses */
530 continue;
531 }
532 } else {
533 if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == INADDR_ANY) {
534 continue;
535 }
536 }
537 if (ifa->ifa_addr->sa_family == AF_INET6) {
538 ifa6 = (struct in6_ifaddr *)ifa;
539 ifa_flags = ifa6->ia6_flags;
540 } else {
541 ifa_flags = 0;
542 }
543 snprintf(name, SCTP_IFNAMSIZ, "%s%d", ifnet_name(ifn), ifnet_unit(ifn));
544 sctp_ifa = sctp_add_addr_to_vrf(vrfid,
545 (void *)ifn, /* XXX */
546 ifnet_index(ifn),
547 ifnet_type(ifn),
548 name,
549 (void *)ifa, /* XXX */
550 ifa->ifa_addr,
551 ifa_flags,
552 0);
553 if (sctp_ifa) {
554 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
555 }
556 }
557 ifnet_free_address_list(ifaddrlist);
558 }
559 ifnet_list_free(ifnetlist);
560 }
561 #endif
562
563 #if defined(__FreeBSD__)
564 static void
565 sctp_init_ifns_for_vrf(int vrfid)
566 {
567 /* Here we must apply ANY locks needed by the
568 * IFN we access and also make sure we lock
569 * any IFA that exists as we float through the
570 * list of IFA's
571 */
572 struct epoch_tracker et;
573 struct ifnet *ifn;
574 struct ifaddr *ifa;
575 struct sctp_ifa *sctp_ifa;
576 uint32_t ifa_flags;
577 #ifdef INET6
578 struct in6_ifaddr *ifa6;
579 #endif
580
581 IFNET_RLOCK();
582 NET_EPOCH_ENTER(et);
583 CK_STAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
584 if (sctp_is_desired_interface_type(ifn) == 0) {
585 /* non desired type */
586 continue;
587 }
588 CK_STAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
589 if (ifa->ifa_addr == NULL) {
590 continue;
591 }
592 switch (ifa->ifa_addr->sa_family) {
593 #ifdef INET
594 case AF_INET:
595 if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
596 continue;
597 }
598 break;
599 #endif
600 #ifdef INET6
601 case AF_INET6:
602 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
603 /* skip unspecifed addresses */
604 continue;
605 }
606 break;
607 #endif
608 default:
609 continue;
610 }
611 switch (ifa->ifa_addr->sa_family) {
612 #ifdef INET
613 case AF_INET:
614 ifa_flags = 0;
615 break;
616 #endif
617 #ifdef INET6
618 case AF_INET6:
619 ifa6 = (struct in6_ifaddr *)ifa;
620 ifa_flags = ifa6->ia6_flags;
621 break;
622 #endif
623 default:
624 ifa_flags = 0;
625 break;
626 }
627 sctp_ifa = sctp_add_addr_to_vrf(vrfid,
628 (void *)ifn,
629 ifn->if_index,
630 ifn->if_type,
631 ifn->if_xname,
632 (void *)ifa,
633 ifa->ifa_addr,
634 ifa_flags,
635 0);
636 if (sctp_ifa) {
637 sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
638 }
639 }
640 }
641 NET_EPOCH_EXIT(et);
642 IFNET_RUNLOCK();
643 }
644 #endif
645
646 void
647 sctp_init_vrf_list(int vrfid)
648 {
649 if (vrfid > SCTP_MAX_VRF_ID)
650 /* can't do that */
651 return;
652
653 /* Don't care about return here */
654 (void)sctp_allocate_vrf(vrfid);
655
656 /* Now we need to build all the ifn's
657 * for this vrf and there addresses
658 */
659 sctp_init_ifns_for_vrf(vrfid);
660 }
661
662 void
663 sctp_addr_change(struct ifaddr *ifa, int cmd)
664 {
665 #if defined(__Userspace__)
666 return;
667 #else
668 uint32_t ifa_flags = 0;
669
670 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
671 return;
672 }
673 /* BSD only has one VRF, if this changes
674 * we will need to hook in the right
675 * things here to get the id to pass to
676 * the address management routine.
677 */
678 if (SCTP_BASE_VAR(first_time) == 0) {
679 /* Special test to see if my ::1 will showup with this */
680 SCTP_BASE_VAR(first_time) = 1;
681 sctp_init_ifns_for_vrf(SCTP_DEFAULT_VRFID);
682 }
683
684 if ((cmd != RTM_ADD) && (cmd != RTM_DELETE)) {
685 /* don't know what to do with this */
686 return;
687 }
688
689 if (ifa->ifa_addr == NULL) {
690 return;
691 }
692 if (sctp_is_desired_interface_type(ifa->ifa_ifp) == 0) {
693 /* non desired type */
694 return;
695 }
696 switch (ifa->ifa_addr->sa_family) {
697 #ifdef INET
698 case AF_INET:
699 if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
700 return;
701 }
702 break;
703 #endif
704 #ifdef INET6
705 case AF_INET6:
706 ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
707 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
708 /* skip unspecifed addresses */
709 return;
710 }
711 break;
712 #endif
713 default:
714 /* non inet/inet6 skip */
715 return;
716 }
717 if (cmd == RTM_ADD) {
718 (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp,
719 #if defined(__APPLE__)
720 ifnet_index(ifa->ifa_ifp), ifnet_type(ifa->ifa_ifp), ifnet_name(ifa->ifa_ifp),
721 #else
722 ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname,
723 #endif
724 (void *)ifa, ifa->ifa_addr, ifa_flags, 1);
725 } else {
726
727 sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
728 #if defined(__APPLE__)
729 ifnet_index(ifa->ifa_ifp),
730 ifnet_name(ifa->ifa_ifp));
731 #else
732 ifa->ifa_ifp->if_index,
733 ifa->ifa_ifp->if_xname);
734 #endif
735
736 /* We don't bump refcount here so when it completes
737 * the final delete will happen.
738 */
739 }
740 #endif
741 }
742
743 #if defined(__FreeBSD__)
744 void
745 sctp_addr_change_event_handler(void *arg __unused, struct ifaddr *ifa, int cmd) {
746 sctp_addr_change(ifa, cmd);
747 }
748
749 void
750 sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
751 {
752 struct ifnet *ifn;
753 struct ifaddr *ifa;
754
755 IFNET_RLOCK();
756 CK_STAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
757 if (!(*pred)(ifn)) {
758 continue;
759 }
760 CK_STAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
761 sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
762 }
763 }
764 IFNET_RUNLOCK();
765 }
766 #endif
767 #if defined(__APPLE__)
768 void
769 sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
770 {
771 struct ifnet **ifnetlist;
772 struct ifaddr **ifaddrlist;
773 uint32_t i, j, count;
774
775 if (ifnet_list_get(IFNET_FAMILY_ANY, &ifnetlist, &count) != 0) {
776 return;
777 }
778 for (i = 0; i < count; i++) {
779 if (!(*pred)(ifnetlist[i])) {
780 continue;
781 }
782 if (ifnet_get_address_list(ifnetlist[i], &ifaddrlist) != 0) {
783 continue;
784 }
785 for (j = 0; ifaddrlist[j] != NULL; j++) {
786 sctp_addr_change(ifaddrlist[j], add ? RTM_ADD : RTM_DELETE);
787 }
788 ifnet_free_address_list(ifaddrlist);
789 }
790 ifnet_list_free(ifnetlist);
791 return;
792 }
793 #endif
794
795 struct mbuf *
796 sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
797 int how, int allonebuf, int type)
798 {
799 struct mbuf *m = NULL;
800 #if defined(__FreeBSD__) && __FreeBSD_version > 1100052 || defined(__Userspace__)
801 #if defined(__Userspace__)
802 m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
803 #else
804 m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
805 #endif
806 if (m == NULL) {
807 /* bad, no memory */
808 return (m);
809 }
810 #if !defined(__Userspace__)
811 if (allonebuf) {
812 if (SCTP_BUF_SIZE(m) < space_needed) {
813 m_freem(m);
814 return (NULL);
815 }
816 KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __FUNCTION__));
817 }
818 #endif
819 #ifdef SCTP_MBUF_LOGGING
820 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
821 sctp_log_mb(m, SCTP_MBUF_IALLOC);
822 }
823 #endif
824 #else
825 int mbuf_threshold;
826 unsigned int size;
827
828 if (want_header) {
829 MGETHDR(m, how, type);
830 size = MHLEN;
831 } else {
832 MGET(m, how, type);
833 size = MLEN;
834 }
835 if (m == NULL) {
836 return (NULL);
837 }
838 if (allonebuf == 0) {
839 mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
840 } else {
841 mbuf_threshold = 1;
842 }
843
844 if (space_needed > (unsigned int)(((mbuf_threshold - 1) * MLEN) + MHLEN)) {
845 MCLGET(m, how);
846 if (m == NULL) {
847 return (NULL);
848 }
849 if (SCTP_BUF_IS_EXTENDED(m) == 0) {
850 sctp_m_freem(m);
851 return (NULL);
852 }
853 size = SCTP_BUF_EXTEND_SIZE(m);
854 }
855 if (allonebuf != 0 && size < space_needed) {
856 m_freem(m);
857 return (NULL);
858 }
859 SCTP_BUF_LEN(m) = 0;
860 SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
861 #ifdef SCTP_MBUF_LOGGING
862 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
863 sctp_log_mb(m, SCTP_MBUF_IALLOC);
864 }
865 #endif
866 #endif
867 return (m);
868 }
869
870
871 #ifdef SCTP_PACKET_LOGGING
872 void
873 sctp_packet_log(struct mbuf *m)
874 {
875 int *lenat, thisone;
876 void *copyto;
877 uint32_t *tick_tock;
878 int length;
879 int total_len;
880 int grabbed_lock = 0;
881 int value, newval, thisend, thisbegin;
882 /*
883 * Buffer layout.
884 * -sizeof this entry (total_len)
885 * -previous end (value)
886 * -ticks of log (ticks)
887 * o -ip packet
888 * o -as logged
889 * - where this started (thisbegin)
890 * x <--end points here
891 */
892 length = SCTP_HEADER_LEN(m);
893 total_len = SCTP_SIZE32((length + (4 * sizeof(int))));
894 /* Log a packet to the buffer. */
895 if (total_len> SCTP_PACKET_LOG_SIZE) {
896 /* Can't log this packet I have not a buffer big enough */
897 return;
898 }
899 if (length < (int)(SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
900 return;
901 }
902 atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), 1);
903 try_again:
904 if (SCTP_BASE_VAR(packet_log_writers) > SCTP_PKTLOG_WRITERS_NEED_LOCK) {
905 SCTP_IP_PKTLOG_LOCK();
906 grabbed_lock = 1;
907 again_locked:
908 value = SCTP_BASE_VAR(packet_log_end);
909 newval = SCTP_BASE_VAR(packet_log_end) + total_len;
910 if (newval >= SCTP_PACKET_LOG_SIZE) {
911 /* we wrapped */
912 thisbegin = 0;
913 thisend = total_len;
914 } else {
915 thisbegin = SCTP_BASE_VAR(packet_log_end);
916 thisend = newval;
917 }
918 if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
919 goto again_locked;
920 }
921 } else {
922 value = SCTP_BASE_VAR(packet_log_end);
923 newval = SCTP_BASE_VAR(packet_log_end) + total_len;
924 if (newval >= SCTP_PACKET_LOG_SIZE) {
925 /* we wrapped */
926 thisbegin = 0;
927 thisend = total_len;
928 } else {
929 thisbegin = SCTP_BASE_VAR(packet_log_end);
930 thisend = newval;
931 }
932 if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
933 goto try_again;
934 }
935 }
936 /* Sanity check */
937 if (thisend >= SCTP_PACKET_LOG_SIZE) {
938 SCTP_PRINTF("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n",
939 thisbegin,
940 thisend,
941 SCTP_BASE_VAR(packet_log_writers),
942 grabbed_lock,
943 SCTP_BASE_VAR(packet_log_end));
944 SCTP_BASE_VAR(packet_log_end) = 0;
945 goto no_log;
946
947 }
948 lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
949 *lenat = total_len;
950 lenat++;
951 *lenat = value;
952 lenat++;
953 tick_tock = (uint32_t *)lenat;
954 lenat++;
955 *tick_tock = sctp_get_tick_count();
956 copyto = (void *)lenat;
957 thisone = thisend - sizeof(int);
958 lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisone];
959 *lenat = thisbegin;
960 if (grabbed_lock) {
961 SCTP_IP_PKTLOG_UNLOCK();
962 grabbed_lock = 0;
963 }
964 m_copydata(m, 0, length, (caddr_t)copyto);
965 no_log:
966 if (grabbed_lock) {
967 SCTP_IP_PKTLOG_UNLOCK();
968 }
969 atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
970 }
971
972
973 int
974 sctp_copy_out_packet_log(uint8_t *target, int length)
975 {
976 /* We wind through the packet log starting at
977 * start copying up to length bytes out.
978 * We return the number of bytes copied.
979 */
980 int tocopy, this_copy;
981 int *lenat;
982 int did_delay = 0;
983
984 tocopy = length;
985 if (length < (int)(2 * sizeof(int))) {
986 /* not enough room */
987 return (0);
988 }
989 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
990 atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), SCTP_PKTLOG_WRITERS_NEED_LOCK);
991 again:
992 if ((did_delay == 0) && (SCTP_BASE_VAR(packet_log_writers) != SCTP_PKTLOG_WRITERS_NEED_LOCK)) {
993 /* we delay here for just a moment hoping the writer(s) that were
994 * present when we entered will have left and we only have
995 * locking ones that will contend with us for the lock. This
996 * does not assure 100% access, but its good enough for
997 * a logging facility like this.
998 */
999 did_delay = 1;
1000 DELAY(10);
1001 goto again;
1002 }
1003 }
1004 SCTP_IP_PKTLOG_LOCK();
1005 lenat = (int *)target;
1006 *lenat = SCTP_BASE_VAR(packet_log_end);
1007 lenat++;
1008 this_copy = min((length - sizeof(int)), SCTP_PACKET_LOG_SIZE);
1009 memcpy((void *)lenat, (void *)SCTP_BASE_VAR(packet_log_buffer), this_copy);
1010 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
1011 atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers),
1012 SCTP_PKTLOG_WRITERS_NEED_LOCK);
1013 }
1014 SCTP_IP_PKTLOG_UNLOCK();
1015 return (this_copy + sizeof(int));
1016 }
1017
1018 #endif
1019