* The caller must make sure the protocol and its functions correctly shut down * all sockets and release all locks and memory references. */
| 401 | * all sockets and release all locks and memory references. |
| 402 | */ |
| 403 | int |
| 404 | pf_proto_unregister(int family, int protocol, int type) |
| 405 | { |
| 406 | struct domain *dp; |
| 407 | struct protosw *pr, *dpr; |
| 408 | |
| 409 | /* Sanity checks. */ |
| 410 | if (family == 0) |
| 411 | return (EPFNOSUPPORT); |
| 412 | if (protocol == 0) |
| 413 | return (EPROTONOSUPPORT); |
| 414 | if (type == 0) |
| 415 | return (EPROTOTYPE); |
| 416 | |
| 417 | /* Try to find the specified domain based on the family type. */ |
| 418 | dp = pffinddomain(family); |
| 419 | if (dp == NULL) |
| 420 | return (EPFNOSUPPORT); |
| 421 | |
| 422 | dpr = NULL; |
| 423 | |
| 424 | /* Lock out everyone else while we are manipulating the protosw. */ |
| 425 | mtx_lock(&dom_mtx); |
| 426 | |
| 427 | /* The protocol must exist and only once. */ |
| 428 | for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { |
| 429 | if ((pr->pr_type == type) && (pr->pr_protocol == protocol)) { |
| 430 | if (dpr != NULL) { |
| 431 | mtx_unlock(&dom_mtx); |
| 432 | return (EMLINK); /* Should not happen! */ |
| 433 | } else |
| 434 | dpr = pr; |
| 435 | } |
| 436 | } |
| 437 | |
| 438 | /* Protocol does not exist. */ |
| 439 | if (dpr == NULL) { |
| 440 | mtx_unlock(&dom_mtx); |
| 441 | return (EPROTONOSUPPORT); |
| 442 | } |
| 443 | |
| 444 | /* De-orbit the protocol and make the slot available again. */ |
| 445 | dpr->pr_type = 0; |
| 446 | dpr->pr_domain = dp; |
| 447 | dpr->pr_protocol = PROTO_SPACER; |
| 448 | dpr->pr_flags = 0; |
| 449 | dpr->pr_input = NULL; |
| 450 | dpr->pr_output = NULL; |
| 451 | dpr->pr_ctlinput = NULL; |
| 452 | dpr->pr_ctloutput = NULL; |
| 453 | dpr->pr_init = NULL; |
| 454 | dpr->pr_fasttimo = NULL; |
| 455 | dpr->pr_slowtimo = NULL; |
| 456 | dpr->pr_drain = NULL; |
| 457 | dpr->pr_usrreqs = &nousrreqs; |
| 458 | |
| 459 | /* Job is done, not more protection required. */ |
| 460 | mtx_unlock(&dom_mtx); |
no test coverage detected