1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1982, 1986, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/protosw.h> 40 #include <sys/domain.h> 41 #include <sys/eventhandler.h> 42 #include <sys/epoch.h> 43 #include <sys/mbuf.h> 44 #include <sys/kernel.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <sys/rmlock.h> 48 #include <sys/socketvar.h> 49 #include <sys/systm.h> 50 #include <sys/stat.h> /* XXXGL: remove */ 51 52 #include <machine/atomic.h> 53 54 #include <net/vnet.h> 55 56 /* 57 * System initialization 58 * 59 * Note: domain initialization takes place on a per domain basis 60 * as a result of traversing a SYSINIT linker set. Most likely, 61 * each domain would want to call DOMAIN_SET(9) itself, which 62 * would cause the domain to be added just after domaininit() 63 * is called during startup. 64 * 65 * See DOMAIN_SET(9) for details on its use. 66 */ 67 68 static void domaininit(void *); 69 SYSINIT(domain, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, domaininit, NULL); 70 71 static void domainfinalize(void *); 72 SYSINIT(domainfin, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, domainfinalize, 73 NULL); 74 75 struct domain *domains; /* registered protocol domains */ 76 int domain_init_status = 0; 77 static struct mtx dom_mtx; /* domain list lock */ 78 MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF); 79 80 static int 81 pr_accept_notsupp(struct socket *so, struct sockaddr **nam) 82 { 83 return (EOPNOTSUPP); 84 } 85 86 static int 87 pr_aio_queue_notsupp(struct socket *so, struct kaiocb *job) 88 { 89 return (EOPNOTSUPP); 90 } 91 92 static int 93 pr_bind_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) 94 { 95 return (EOPNOTSUPP); 96 } 97 98 static int 99 pr_bindat_notsupp(int fd, struct socket *so, struct sockaddr *nam, 100 struct thread *td) 101 { 102 return (EOPNOTSUPP); 103 } 104 105 static int 106 pr_connect_notsupp(struct socket *so, struct sockaddr *nam, struct thread *td) 107 { 108 return (EOPNOTSUPP); 109 } 110 111 static int 112 pr_connectat_notsupp(int fd, struct socket *so, struct sockaddr *nam, 113 struct thread *td) 114 { 115 return (EOPNOTSUPP); 116 } 117 118 static int 119 pr_connect2_notsupp(struct socket *so1, struct socket *so2) 120 { 121 return (EOPNOTSUPP); 122 } 123 124 static int 125 pr_control_notsupp(struct socket *so, u_long cmd, void *data, 126 struct ifnet *ifp, struct thread *td) 127 { 128 return (EOPNOTSUPP); 129 } 130 131 static int 132 pr_disconnect_notsupp(struct socket *so) 133 { 134 return (EOPNOTSUPP); 135 } 136 137 static int 138 pr_listen_notsupp(struct socket *so, int backlog, struct thread *td) 139 { 140 return (EOPNOTSUPP); 141 } 142 143 static int 144 pr_peeraddr_notsupp(struct socket *so, struct sockaddr **nam) 145 { 146 return (EOPNOTSUPP); 147 } 148 149 static int 150 pr_rcvd_notsupp(struct socket *so, int flags) 151 { 152 return (EOPNOTSUPP); 153 } 154 155 static int 156 pr_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags) 157 { 158 return (EOPNOTSUPP); 159 } 160 161 static int 162 pr_send_notsupp(struct socket *so, int flags, struct mbuf *m, 163 struct sockaddr *addr, struct mbuf *control, struct thread *td) 164 { 165 if (control != NULL) 166 m_freem(control); 167 if ((flags & PRUS_NOTREADY) == 0) 168 m_freem(m); 169 return (EOPNOTSUPP); 170 } 171 172 static int 173 pr_ready_notsupp(struct socket *so, struct mbuf *m, int count) 174 { 175 return (EOPNOTSUPP); 176 } 177 178 /* 179 * This isn't really a ``null'' operation, but it's the default one and 180 * doesn't do anything destructive. 181 */ 182 static int 183 pr_sense_notsupp(struct socket *so, struct stat *sb) 184 { 185 sb->st_blksize = so->so_snd.sb_hiwat; 186 return (0); 187 } 188 189 static int 190 pr_shutdown_notsupp(struct socket *so) 191 { 192 return (EOPNOTSUPP); 193 } 194 195 static int 196 pr_sockaddr_notsupp(struct socket *so, struct sockaddr **nam) 197 { 198 return (EOPNOTSUPP); 199 } 200 201 static int 202 pr_sosend_notsupp(struct socket *so, struct sockaddr *addr, struct uio *uio, 203 struct mbuf *top, struct mbuf *control, int flags, struct thread *td) 204 { 205 return (EOPNOTSUPP); 206 } 207 208 static int 209 pr_soreceive_notsupp(struct socket *so, struct sockaddr **paddr, 210 struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp) 211 { 212 return (EOPNOTSUPP); 213 } 214 215 static int 216 pr_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, 217 struct thread *td) 218 { 219 return (EOPNOTSUPP); 220 } 221 222 static void 223 pr_init(struct protosw *pr) 224 { 225 226 KASSERT(pr->pr_attach != NULL, 227 ("%s: protocol doesn't have pr_attach", __func__)); 228 229 #define DEFAULT(foo, bar) if (pr->foo == NULL) pr->foo = bar 230 DEFAULT(pr_sosend, sosend_generic); 231 DEFAULT(pr_soreceive, soreceive_generic); 232 DEFAULT(pr_sopoll, sopoll_generic); 233 234 #define NOTSUPP(foo) if (pr->foo == NULL) pr->foo = foo ## _notsupp 235 NOTSUPP(pr_accept); 236 NOTSUPP(pr_aio_queue); 237 NOTSUPP(pr_bind); 238 NOTSUPP(pr_bindat); 239 NOTSUPP(pr_connect); 240 NOTSUPP(pr_connect2); 241 NOTSUPP(pr_connectat); 242 NOTSUPP(pr_control); 243 NOTSUPP(pr_disconnect); 244 NOTSUPP(pr_listen); 245 NOTSUPP(pr_peeraddr); 246 NOTSUPP(pr_rcvd); 247 NOTSUPP(pr_rcvoob); 248 NOTSUPP(pr_send); 249 NOTSUPP(pr_sense); 250 NOTSUPP(pr_shutdown); 251 NOTSUPP(pr_sockaddr); 252 NOTSUPP(pr_sosend); 253 NOTSUPP(pr_soreceive); 254 NOTSUPP(pr_sopoll); 255 NOTSUPP(pr_ready); 256 } 257 258 /* 259 * Add a new protocol domain to the list of supported domains 260 * Note: you cant unload it again because a socket may be using it. 261 * XXX can't fail at this time. 262 */ 263 void 264 domain_init(void *arg) 265 { 266 struct domain *dp = arg; 267 struct protosw *pr; 268 int flags; 269 270 MPASS(IS_DEFAULT_VNET(curvnet)); 271 272 flags = atomic_load_acq_int(&dp->dom_flags); 273 if ((flags & DOMF_SUPPORTED) == 0) 274 return; 275 MPASS((flags & DOMF_INITED) == 0); 276 277 for (int i = 0; i < dp->dom_nprotosw; i++) 278 if ((pr = dp->dom_protosw[i]) != NULL) { 279 pr->pr_domain = dp; 280 pr_init(pr); 281 } 282 283 /* 284 * update global information about maximums 285 */ 286 max_hdr = max_linkhdr + max_protohdr; 287 max_datalen = MHLEN - max_hdr; 288 if (max_datalen < 1) 289 panic("%s: max_datalen < 1", __func__); 290 atomic_set_rel_int(&dp->dom_flags, DOMF_INITED); 291 } 292 293 /* 294 * Add a new protocol domain to the list of supported domains 295 * Note: you cant unload it again because a socket may be using it. 296 * XXX can't fail at this time. 297 */ 298 void 299 domain_add(void *data) 300 { 301 struct domain *dp; 302 303 dp = (struct domain *)data; 304 if (dp->dom_probe != NULL && (*dp->dom_probe)() != 0) 305 return; 306 atomic_set_rel_int(&dp->dom_flags, DOMF_SUPPORTED); 307 mtx_lock(&dom_mtx); 308 dp->dom_next = domains; 309 domains = dp; 310 311 KASSERT(domain_init_status >= 1, 312 ("attempt to domain_add(%s) before domaininit()", 313 dp->dom_name)); 314 #ifndef INVARIANTS 315 if (domain_init_status < 1) 316 printf("WARNING: attempt to domain_add(%s) before " 317 "domaininit()\n", dp->dom_name); 318 #endif 319 mtx_unlock(&dom_mtx); 320 } 321 322 void 323 domain_remove(void *data) 324 { 325 struct domain *dp = (struct domain *)data; 326 327 if ((dp->dom_flags & DOMF_UNLOADABLE) == 0) 328 return; 329 330 mtx_lock(&dom_mtx); 331 if (domains == dp) { 332 domains = dp->dom_next; 333 } else { 334 struct domain *curr; 335 for (curr = domains; curr != NULL; curr = curr->dom_next) { 336 if (curr->dom_next == dp) { 337 curr->dom_next = dp->dom_next; 338 break; 339 } 340 } 341 } 342 mtx_unlock(&dom_mtx); 343 } 344 345 /* ARGSUSED*/ 346 static void 347 domaininit(void *dummy) 348 { 349 350 if (max_linkhdr < 16) /* XXX */ 351 max_linkhdr = 16; 352 353 mtx_lock(&dom_mtx); 354 KASSERT(domain_init_status == 0, ("domaininit called too late!")); 355 domain_init_status = 1; 356 mtx_unlock(&dom_mtx); 357 } 358 359 /* ARGSUSED*/ 360 static void 361 domainfinalize(void *dummy) 362 { 363 364 mtx_lock(&dom_mtx); 365 KASSERT(domain_init_status == 1, ("domainfinalize called too late!")); 366 domain_init_status = 2; 367 mtx_unlock(&dom_mtx); 368 } 369 370 struct domain * 371 pffinddomain(int family) 372 { 373 struct domain *dp; 374 375 for (dp = domains; dp != NULL; dp = dp->dom_next) 376 if (dp->dom_family == family) 377 return (dp); 378 return (NULL); 379 } 380 381 struct protosw * 382 pffindtype(int family, int type) 383 { 384 struct domain *dp; 385 struct protosw *pr; 386 387 dp = pffinddomain(family); 388 if (dp == NULL) 389 return (NULL); 390 391 for (int i = 0; i < dp->dom_nprotosw; i++) 392 if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type) 393 return (pr); 394 395 return (NULL); 396 } 397 398 struct protosw * 399 pffindproto(int family, int protocol, int type) 400 { 401 struct domain *dp; 402 struct protosw *pr; 403 struct protosw *maybe; 404 405 dp = pffinddomain(family); 406 if (dp == NULL) 407 return (NULL); 408 409 maybe = NULL; 410 for (int i = 0; i < dp->dom_nprotosw; i++) { 411 if ((pr = dp->dom_protosw[i]) == NULL) 412 continue; 413 if ((pr->pr_protocol == protocol) && (pr->pr_type == type)) 414 return (pr); 415 416 /* XXX: raw catches all. Why? */ 417 if (type == SOCK_RAW && pr->pr_type == SOCK_RAW && 418 pr->pr_protocol == 0 && maybe == NULL) 419 maybe = pr; 420 } 421 return (maybe); 422 } 423 424 /* 425 * The caller must make sure that the new protocol is fully set up and ready to 426 * accept requests before it is registered. 427 */ 428 int 429 protosw_register(struct domain *dp, struct protosw *npr) 430 { 431 struct protosw **prp; 432 433 MPASS(dp); 434 MPASS(npr && npr->pr_type > 0 && npr->pr_protocol > 0); 435 436 prp = NULL; 437 /* 438 * Protect us against races when two protocol registrations for 439 * the same protocol happen at the same time. 440 */ 441 mtx_lock(&dom_mtx); 442 for (int i = 0; i < dp->dom_nprotosw; i++) { 443 if (dp->dom_protosw[i] == NULL) { 444 /* Remember the first free spacer. */ 445 if (prp == NULL) 446 prp = &dp->dom_protosw[i]; 447 } else { 448 /* 449 * The new protocol must not yet exist. 450 * XXXAO: Check only protocol? 451 * XXXGL: Maybe assert that it doesn't exist? 452 */ 453 if ((dp->dom_protosw[i]->pr_type == npr->pr_type) && 454 (dp->dom_protosw[i]->pr_protocol == 455 npr->pr_protocol)) { 456 mtx_unlock(&dom_mtx); 457 return (EEXIST); 458 } 459 460 } 461 } 462 463 /* If no free spacer is found we can't add the new protocol. */ 464 if (prp == NULL) { 465 mtx_unlock(&dom_mtx); 466 return (ENOMEM); 467 } 468 469 npr->pr_domain = dp; 470 pr_init(npr); 471 *prp = npr; 472 mtx_unlock(&dom_mtx); 473 474 return (0); 475 } 476 477 /* 478 * The caller must make sure the protocol and its functions correctly shut down 479 * all sockets and release all locks and memory references. 480 */ 481 int 482 protosw_unregister(struct protosw *pr) 483 { 484 struct domain *dp; 485 struct protosw **prp; 486 487 dp = pr->pr_domain; 488 prp = NULL; 489 490 mtx_lock(&dom_mtx); 491 /* The protocol must exist and only once. */ 492 for (int i = 0; i < dp->dom_nprotosw; i++) { 493 if (dp->dom_protosw[i] == pr) { 494 KASSERT(prp == NULL, 495 ("%s: domain %p protocol %p registered twice\n", 496 __func__, dp, pr)); 497 prp = &dp->dom_protosw[i]; 498 } 499 } 500 501 /* Protocol does not exist. XXXGL: assert that it does? */ 502 if (prp == NULL) { 503 mtx_unlock(&dom_mtx); 504 return (EPROTONOSUPPORT); 505 } 506 507 /* De-orbit the protocol and make the slot available again. */ 508 *prp = NULL; 509 mtx_unlock(&dom_mtx); 510 511 return (0); 512 } 513