uipc_domain.c revision 275329
144819Smjacob/*-
244819Smjacob * Copyright (c) 1982, 1986, 1993
335388Smjacob *	The Regents of the University of California.  All rights reserved.
435388Smjacob *
535388Smjacob * Redistribution and use in source and binary forms, with or without
635388Smjacob * modification, are permitted provided that the following conditions
735388Smjacob * are met:
835388Smjacob * 1. Redistributions of source code must retain the above copyright
935388Smjacob *    notice, this list of conditions and the following disclaimer.
1035388Smjacob * 2. Redistributions in binary form must reproduce the above copyright
1135388Smjacob *    notice, this list of conditions and the following disclaimer in the
1235388Smjacob *    documentation and/or other materials provided with the distribution.
1335388Smjacob * 4. Neither the name of the University nor the names of its contributors
1435388Smjacob *    may be used to endorse or promote products derived from this software
1535388Smjacob *    without specific prior written permission.
1635388Smjacob *
1735388Smjacob * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1835388Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1935388Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2035388Smjacob * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2135388Smjacob * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2235388Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2335388Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2435388Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2535388Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2635388Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2735388Smjacob * SUCH DAMAGE.
2835388Smjacob *
2935388Smjacob *	@(#)uipc_domain.c	8.2 (Berkeley) 10/18/93
3035388Smjacob */
3135388Smjacob
3235388Smjacob#include <sys/cdefs.h>
3335388Smjacob__FBSDID("$FreeBSD: head/sys/kern/uipc_domain.c 275329 2014-11-30 13:24:21Z glebius $");
3435388Smjacob
3535388Smjacob#include <sys/param.h>
3635388Smjacob#include <sys/socket.h>
3735388Smjacob#include <sys/protosw.h>
3835388Smjacob#include <sys/domain.h>
3935388Smjacob#include <sys/eventhandler.h>
4035388Smjacob#include <sys/mbuf.h>
4135388Smjacob#include <sys/kernel.h>
4235388Smjacob#include <sys/lock.h>
4335388Smjacob#include <sys/mutex.h>
4435388Smjacob#include <sys/socketvar.h>
4535388Smjacob#include <sys/systm.h>
4635388Smjacob
4735388Smjacob#include <net/vnet.h>
4835388Smjacob
4935388Smjacob/*
5035388Smjacob * System initialization
5135388Smjacob *
5235388Smjacob * Note: domain initialization takes place on a per domain basis
5335388Smjacob * as a result of traversing a SYSINIT linker set.  Most likely,
5435388Smjacob * each domain would want to call DOMAIN_SET(9) itself, which
5535388Smjacob * would cause the domain to be added just after domaininit()
5635388Smjacob * is called during startup.
5735388Smjacob *
5835388Smjacob * See DOMAIN_SET(9) for details on its use.
5935388Smjacob */
6044819Smjacob
6135388Smjacobstatic void domaininit(void *);
6244819SmjacobSYSINIT(domain, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, domaininit, NULL);
6344819Smjacob
6435388Smjacobstatic void domainfinalize(void *);
6535388SmjacobSYSINIT(domainfin, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, domainfinalize,
6644819Smjacob    NULL);
6735388Smjacob
6835388Smjacobstatic struct callout pffast_callout;
6944819Smjacobstatic struct callout pfslow_callout;
7035388Smjacob
7135388Smjacobstatic void	pffasttimo(void *);
7244819Smjacobstatic void	pfslowtimo(void *);
7344819Smjacob
7444819Smjacobstruct domain *domains;		/* registered protocol domains */
7544819Smjacobint domain_init_status = 0;
7635388Smjacobstatic struct mtx dom_mtx;		/* domain list lock */
7735388SmjacobMTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF);
7835388Smjacob
7935388Smjacob/*
8035388Smjacob * Dummy protocol specific user requests function pointer array.
8144819Smjacob * All functions return EOPNOTSUPP.
8244819Smjacob */
8344819Smjacobstruct pr_usrreqs nousrreqs = {
8444819Smjacob	.pru_accept =		pru_accept_notsupp,
8544819Smjacob	.pru_attach =		pru_attach_notsupp,
8644819Smjacob	.pru_bind =		pru_bind_notsupp,
8744819Smjacob	.pru_connect =		pru_connect_notsupp,
8844819Smjacob	.pru_connect2 =		pru_connect2_notsupp,
8935388Smjacob	.pru_control =		pru_control_notsupp,
9035388Smjacob	.pru_disconnect	=	pru_disconnect_notsupp,
9135388Smjacob	.pru_listen =		pru_listen_notsupp,
9235388Smjacob	.pru_peeraddr =		pru_peeraddr_notsupp,
9344819Smjacob	.pru_rcvd =		pru_rcvd_notsupp,
9435388Smjacob	.pru_rcvoob =		pru_rcvoob_notsupp,
9535388Smjacob	.pru_send =		pru_send_notsupp,
9635388Smjacob	.pru_sense =		pru_sense_null,
9735388Smjacob	.pru_shutdown =		pru_shutdown_notsupp,
9835388Smjacob	.pru_sockaddr =		pru_sockaddr_notsupp,
9935388Smjacob	.pru_sosend =		pru_sosend_notsupp,
10035388Smjacob	.pru_soreceive =	pru_soreceive_notsupp,
10135388Smjacob	.pru_sopoll =		pru_sopoll_notsupp,
10235388Smjacob};
10335388Smjacob
10435388Smjacobstatic void
10544819Smjacobprotosw_init(struct protosw *pr)
10644819Smjacob{
10744819Smjacob	struct pr_usrreqs *pu;
10844819Smjacob
10944819Smjacob	pu = pr->pr_usrreqs;
11044819Smjacob	KASSERT(pu != NULL, ("protosw_init: %ssw[%d] has no usrreqs!",
11144819Smjacob	    pr->pr_domain->dom_name,
11244819Smjacob	    (int)(pr - pr->pr_domain->dom_protosw)));
11335388Smjacob
11444819Smjacob	/*
11544819Smjacob	 * Protocol switch methods fall into three categories: mandatory,
11644819Smjacob	 * mandatory but protosw_init() provides a default, and optional.
11744819Smjacob	 *
11844819Smjacob	 * For true protocols (i.e., pru_attach != NULL), KASSERT truly
11944819Smjacob	 * mandatory methods with no defaults, and initialize defaults for
12044819Smjacob	 * other mandatory methods if the protocol hasn't defined an
12144819Smjacob	 * implementation (NULL function pointer).
12235388Smjacob	 */
12344819Smjacob#if 0
12435388Smjacob	if (pu->pru_attach != NULL) {
12544819Smjacob		KASSERT(pu->pru_abort != NULL,
12644819Smjacob		    ("protosw_init: %ssw[%d] pru_abort NULL",
12744819Smjacob		    pr->pr_domain->dom_name,
12844819Smjacob		    (int)(pr - pr->pr_domain->dom_protosw)));
12944819Smjacob		KASSERT(pu->pru_send != NULL,
13044819Smjacob		    ("protosw_init: %ssw[%d] pru_send NULL",
13144819Smjacob		    pr->pr_domain->dom_name,
13235388Smjacob		    (int)(pr - pr->pr_domain->dom_protosw)));
13344819Smjacob	}
13444819Smjacob#endif
13535388Smjacob
13635388Smjacob#define DEFAULT(foo, bar)	if ((foo) == NULL)  (foo) = (bar)
13735388Smjacob	DEFAULT(pu->pru_accept, pru_accept_notsupp);
13835388Smjacob	DEFAULT(pu->pru_bind, pru_bind_notsupp);
13935388Smjacob	DEFAULT(pu->pru_bindat, pru_bindat_notsupp);
14035388Smjacob	DEFAULT(pu->pru_connect, pru_connect_notsupp);
14135388Smjacob	DEFAULT(pu->pru_connect2, pru_connect2_notsupp);
14235388Smjacob	DEFAULT(pu->pru_connectat, pru_connectat_notsupp);
14335388Smjacob	DEFAULT(pu->pru_control, pru_control_notsupp);
14435388Smjacob	DEFAULT(pu->pru_disconnect, pru_disconnect_notsupp);
14535388Smjacob	DEFAULT(pu->pru_listen, pru_listen_notsupp);
14635388Smjacob	DEFAULT(pu->pru_peeraddr, pru_peeraddr_notsupp);
14735388Smjacob	DEFAULT(pu->pru_rcvd, pru_rcvd_notsupp);
14835388Smjacob	DEFAULT(pu->pru_rcvoob, pru_rcvoob_notsupp);
14935388Smjacob	DEFAULT(pu->pru_sense, pru_sense_null);
15035388Smjacob	DEFAULT(pu->pru_shutdown, pru_shutdown_notsupp);
15135388Smjacob	DEFAULT(pu->pru_sockaddr, pru_sockaddr_notsupp);
15235388Smjacob	DEFAULT(pu->pru_sosend, sosend_generic);
15335388Smjacob	DEFAULT(pu->pru_soreceive, soreceive_generic);
15435388Smjacob	DEFAULT(pu->pru_sopoll, sopoll_generic);
15535388Smjacob	DEFAULT(pu->pru_ready, pru_ready_notsupp);
15635388Smjacob#undef DEFAULT
15735388Smjacob	if (pr->pr_init)
15835388Smjacob		(*pr->pr_init)();
15944819Smjacob}
16044819Smjacob
16144819Smjacob/*
16235388Smjacob * Add a new protocol domain to the list of supported domains
16335388Smjacob * Note: you cant unload it again because a socket may be using it.
16435388Smjacob * XXX can't fail at this time.
16535388Smjacob */
16635388Smjacobvoid
16735388Smjacobdomain_init(void *arg)
16835388Smjacob{
16935388Smjacob	struct domain *dp = arg;
17035388Smjacob	struct protosw *pr;
17135388Smjacob
17235388Smjacob	if (dp->dom_init)
17335388Smjacob		(*dp->dom_init)();
17435388Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
17535388Smjacob		protosw_init(pr);
17635388Smjacob	/*
17735388Smjacob	 * update global information about maximums
17835388Smjacob	 */
17935388Smjacob	max_hdr = max_linkhdr + max_protohdr;
18035388Smjacob	max_datalen = MHLEN - max_hdr;
18135388Smjacob	if (max_datalen < 1)
18235388Smjacob		panic("%s: max_datalen < 1", __func__);
18335388Smjacob}
18435388Smjacob
18535388Smjacob#ifdef VIMAGE
18635388Smjacobvoid
18735388Smjacobvnet_domain_init(void *arg)
18835388Smjacob{
18935388Smjacob
19035388Smjacob	/* Virtualized case is no different -- call init functions. */
19135388Smjacob	domain_init(arg);
19235388Smjacob}
19335388Smjacob
19435388Smjacobvoid
19535388Smjacobvnet_domain_uninit(void *arg)
19644819Smjacob{
19744819Smjacob	struct domain *dp = arg;
19844819Smjacob	struct protosw *pr;
19944819Smjacob
20044819Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
20135388Smjacob		if (pr->pr_destroy)
20235388Smjacob			(*pr->pr_destroy)();
20335388Smjacob	if (dp->dom_destroy)
20435388Smjacob		(*dp->dom_destroy)();
20535388Smjacob}
20635388Smjacob#endif
20735388Smjacob
20835388Smjacob/*
20935388Smjacob * Add a new protocol domain to the list of supported domains
21035388Smjacob * Note: you cant unload it again because a socket may be using it.
21135388Smjacob * XXX can't fail at this time.
21235388Smjacob */
21335388Smjacobvoid
21435388Smjacobdomain_add(void *data)
21535388Smjacob{
21635388Smjacob	struct domain *dp;
21735388Smjacob
21835388Smjacob	dp = (struct domain *)data;
21935388Smjacob	mtx_lock(&dom_mtx);
22035388Smjacob	dp->dom_next = domains;
22135388Smjacob	domains = dp;
22235388Smjacob
22339235Sgibbs	KASSERT(domain_init_status >= 1,
22439235Sgibbs	    ("attempt to domain_add(%s) before domaininit()",
22539235Sgibbs	    dp->dom_name));
22639235Sgibbs#ifndef INVARIANTS
22739235Sgibbs	if (domain_init_status < 1)
22839235Sgibbs		printf("WARNING: attempt to domain_add(%s) before "
22935388Smjacob		    "domaininit()\n", dp->dom_name);
23035388Smjacob#endif
23135388Smjacob#ifdef notyet
23235388Smjacob	KASSERT(domain_init_status < 2,
23335388Smjacob	    ("attempt to domain_add(%s) after domainfinalize()",
23435388Smjacob	    dp->dom_name));
23535388Smjacob#else
23635388Smjacob	if (domain_init_status >= 2)
23735388Smjacob		printf("WARNING: attempt to domain_add(%s) after "
23835388Smjacob		    "domainfinalize()\n", dp->dom_name);
23935388Smjacob#endif
24035388Smjacob	mtx_unlock(&dom_mtx);
24135388Smjacob}
24235388Smjacob
24335388Smjacob/* ARGSUSED*/
24435388Smjacobstatic void
24535388Smjacobdomaininit(void *dummy)
24635388Smjacob{
24735388Smjacob
24835388Smjacob	if (max_linkhdr < 16)		/* XXX */
24935388Smjacob		max_linkhdr = 16;
25035388Smjacob
25135388Smjacob	callout_init(&pffast_callout, CALLOUT_MPSAFE);
25235388Smjacob	callout_init(&pfslow_callout, CALLOUT_MPSAFE);
25335388Smjacob
25435388Smjacob	mtx_lock(&dom_mtx);
25535388Smjacob	KASSERT(domain_init_status == 0, ("domaininit called too late!"));
25635388Smjacob	domain_init_status = 1;
25735388Smjacob	mtx_unlock(&dom_mtx);
25835388Smjacob}
25935388Smjacob
26035388Smjacob/* ARGSUSED*/
26135388Smjacobstatic void
26235388Smjacobdomainfinalize(void *dummy)
26335388Smjacob{
26435388Smjacob
26535388Smjacob	mtx_lock(&dom_mtx);
26635388Smjacob	KASSERT(domain_init_status == 1, ("domainfinalize called too late!"));
26735388Smjacob	domain_init_status = 2;
26835388Smjacob	mtx_unlock(&dom_mtx);
26935388Smjacob
27035388Smjacob	callout_reset(&pffast_callout, 1, pffasttimo, NULL);
27135388Smjacob	callout_reset(&pfslow_callout, 1, pfslowtimo, NULL);
27235388Smjacob}
27335388Smjacob
27435388Smjacobstruct domain *
27535388Smjacobpffinddomain(int family)
27635388Smjacob{
27735388Smjacob	struct domain *dp;
27835388Smjacob
27935388Smjacob	for (dp = domains; dp != NULL; dp = dp->dom_next)
28035388Smjacob		if (dp->dom_family == family)
28135388Smjacob			return (dp);
28235388Smjacob	return (NULL);
28335388Smjacob}
28435388Smjacob
28535388Smjacobstruct protosw *
28635388Smjacobpffindtype(int family, int type)
28735388Smjacob{
28835388Smjacob	struct domain *dp;
28935388Smjacob	struct protosw *pr;
29035388Smjacob
29135388Smjacob	dp = pffinddomain(family);
29235388Smjacob	if (dp == NULL)
29335388Smjacob		return (NULL);
29435388Smjacob
29535388Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
29635388Smjacob		if (pr->pr_type && pr->pr_type == type)
29735388Smjacob			return (pr);
29835388Smjacob	return (NULL);
29935388Smjacob}
30035388Smjacob
30135388Smjacobstruct protosw *
30235388Smjacobpffindproto(int family, int protocol, int type)
30335388Smjacob{
30435388Smjacob	struct domain *dp;
30535388Smjacob	struct protosw *pr;
30635388Smjacob	struct protosw *maybe;
30735388Smjacob
30835388Smjacob	maybe = NULL;
30935388Smjacob	if (family == 0)
31035388Smjacob		return (NULL);
31135388Smjacob
31235388Smjacob	dp = pffinddomain(family);
31335388Smjacob	if (dp == NULL)
31435388Smjacob		return (NULL);
31535388Smjacob
31635388Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
31735388Smjacob		if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
31835388Smjacob			return (pr);
31935388Smjacob
32035388Smjacob		if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
32135388Smjacob		    pr->pr_protocol == 0 && maybe == NULL)
32235388Smjacob			maybe = pr;
32335388Smjacob	}
32435388Smjacob	return (maybe);
32535388Smjacob}
32635388Smjacob
32735388Smjacob/*
32835388Smjacob * The caller must make sure that the new protocol is fully set up and ready to
32935388Smjacob * accept requests before it is registered.
33035388Smjacob */
33135388Smjacobint
33235388Smjacobpf_proto_register(int family, struct protosw *npr)
33335388Smjacob{
33435388Smjacob	VNET_ITERATOR_DECL(vnet_iter);
33535388Smjacob	struct domain *dp;
33635388Smjacob	struct protosw *pr, *fpr;
33735388Smjacob
33835388Smjacob	/* Sanity checks. */
33935388Smjacob	if (family == 0)
34035388Smjacob		return (EPFNOSUPPORT);
34135388Smjacob	if (npr->pr_type == 0)
34235388Smjacob		return (EPROTOTYPE);
34335388Smjacob	if (npr->pr_protocol == 0)
34435388Smjacob		return (EPROTONOSUPPORT);
34535388Smjacob	if (npr->pr_usrreqs == NULL)
34635388Smjacob		return (ENXIO);
34735388Smjacob
34835388Smjacob	/* Try to find the specified domain based on the family. */
34935388Smjacob	dp = pffinddomain(family);
35035388Smjacob	if (dp == NULL)
35135388Smjacob		return (EPFNOSUPPORT);
35235388Smjacob
35335388Smjacob	/* Initialize backpointer to struct domain. */
35435388Smjacob	npr->pr_domain = dp;
35535388Smjacob	fpr = NULL;
35635388Smjacob
35735388Smjacob	/*
35835388Smjacob	 * Protect us against races when two protocol registrations for
35935388Smjacob	 * the same protocol happen at the same time.
36035388Smjacob	 */
36135388Smjacob	mtx_lock(&dom_mtx);
36235388Smjacob
36335388Smjacob	/* The new protocol must not yet exist. */
36435388Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
36535388Smjacob		if ((pr->pr_type == npr->pr_type) &&
36635388Smjacob		    (pr->pr_protocol == npr->pr_protocol)) {
36735388Smjacob			mtx_unlock(&dom_mtx);
36835388Smjacob			return (EEXIST);	/* XXX: Check only protocol? */
36935388Smjacob		}
37035388Smjacob		/* While here, remember the first free spacer. */
37135388Smjacob		if ((fpr == NULL) && (pr->pr_protocol == PROTO_SPACER))
37235388Smjacob			fpr = pr;
37335388Smjacob	}
37435388Smjacob
37535388Smjacob	/* If no free spacer is found we can't add the new protocol. */
37635388Smjacob	if (fpr == NULL) {
37735388Smjacob		mtx_unlock(&dom_mtx);
37835388Smjacob		return (ENOMEM);
37935388Smjacob	}
38035388Smjacob
38135388Smjacob	/* Copy the new struct protosw over the spacer. */
38235388Smjacob	bcopy(npr, fpr, sizeof(*fpr));
38335388Smjacob
38435388Smjacob	/* Job is done, no more protection required. */
38535388Smjacob	mtx_unlock(&dom_mtx);
38635388Smjacob
38735388Smjacob	/* Initialize and activate the protocol. */
38835388Smjacob	VNET_LIST_RLOCK();
38935388Smjacob	VNET_FOREACH(vnet_iter) {
39035388Smjacob		CURVNET_SET_QUIET(vnet_iter);
39135388Smjacob		protosw_init(fpr);
39235388Smjacob		CURVNET_RESTORE();
39335388Smjacob	}
39435388Smjacob	VNET_LIST_RUNLOCK();
39535388Smjacob
39635388Smjacob	return (0);
39735388Smjacob}
39835388Smjacob
39935388Smjacob/*
40035388Smjacob * The caller must make sure the protocol and its functions correctly shut down
40135388Smjacob * all sockets and release all locks and memory references.
40235388Smjacob */
40335388Smjacobint
40435388Smjacobpf_proto_unregister(int family, int protocol, int type)
40535388Smjacob{
40635388Smjacob	struct domain *dp;
40735388Smjacob	struct protosw *pr, *dpr;
40835388Smjacob
40935388Smjacob	/* Sanity checks. */
41035388Smjacob	if (family == 0)
41135388Smjacob		return (EPFNOSUPPORT);
41235388Smjacob	if (protocol == 0)
41335388Smjacob		return (EPROTONOSUPPORT);
41435388Smjacob	if (type == 0)
41535388Smjacob		return (EPROTOTYPE);
41635388Smjacob
41735388Smjacob	/* Try to find the specified domain based on the family type. */
41835388Smjacob	dp = pffinddomain(family);
41935388Smjacob	if (dp == NULL)
42035388Smjacob		return (EPFNOSUPPORT);
42135388Smjacob
42235388Smjacob	dpr = NULL;
42335388Smjacob
42435388Smjacob	/* Lock out everyone else while we are manipulating the protosw. */
42535388Smjacob	mtx_lock(&dom_mtx);
42635388Smjacob
42735388Smjacob	/* The protocol must exist and only once. */
42835388Smjacob	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
42935388Smjacob		if ((pr->pr_type == type) && (pr->pr_protocol == protocol)) {
43035388Smjacob			if (dpr != NULL) {
43135388Smjacob				mtx_unlock(&dom_mtx);
43235388Smjacob				return (EMLINK);   /* Should not happen! */
43335388Smjacob			} else
43435388Smjacob				dpr = pr;
43535388Smjacob		}
43635388Smjacob	}
43735388Smjacob
43835388Smjacob	/* Protocol does not exist. */
43935388Smjacob	if (dpr == NULL) {
44035388Smjacob		mtx_unlock(&dom_mtx);
44135388Smjacob		return (EPROTONOSUPPORT);
44235388Smjacob	}
44335388Smjacob
44435388Smjacob	/* De-orbit the protocol and make the slot available again. */
44535388Smjacob	dpr->pr_type = 0;
44635388Smjacob	dpr->pr_domain = dp;
44735388Smjacob	dpr->pr_protocol = PROTO_SPACER;
44835388Smjacob	dpr->pr_flags = 0;
44935388Smjacob	dpr->pr_input = NULL;
45035388Smjacob	dpr->pr_output = NULL;
45135388Smjacob	dpr->pr_ctlinput = NULL;
45235388Smjacob	dpr->pr_ctloutput = NULL;
45335388Smjacob	dpr->pr_init = NULL;
45435388Smjacob	dpr->pr_fasttimo = NULL;
45535388Smjacob	dpr->pr_slowtimo = NULL;
45635388Smjacob	dpr->pr_drain = NULL;
45735388Smjacob	dpr->pr_usrreqs = &nousrreqs;
45835388Smjacob
45935388Smjacob	/* Job is done, not more protection required. */
46035388Smjacob	mtx_unlock(&dom_mtx);
46135388Smjacob
46235388Smjacob	return (0);
46335388Smjacob}
46435388Smjacob
46535388Smjacobvoid
46635388Smjacobpfctlinput(int cmd, struct sockaddr *sa)
46735388Smjacob{
46835388Smjacob	struct domain *dp;
46935388Smjacob	struct protosw *pr;
47035388Smjacob
47135388Smjacob	for (dp = domains; dp; dp = dp->dom_next)
47235388Smjacob		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
47335388Smjacob			if (pr->pr_ctlinput)
47435388Smjacob				(*pr->pr_ctlinput)(cmd, sa, (void *)0);
47535388Smjacob}
47635388Smjacob
47735388Smjacobvoid
47835388Smjacobpfctlinput2(int cmd, struct sockaddr *sa, void *ctlparam)
47935388Smjacob{
48035388Smjacob	struct domain *dp;
48135388Smjacob	struct protosw *pr;
48235388Smjacob
48335388Smjacob	if (!sa)
48435388Smjacob		return;
48535388Smjacob	for (dp = domains; dp; dp = dp->dom_next) {
48635388Smjacob		/*
48735388Smjacob		 * the check must be made by xx_ctlinput() anyways, to
48835388Smjacob		 * make sure we use data item pointed to by ctlparam in
48935388Smjacob		 * correct way.  the following check is made just for safety.
49035388Smjacob		 */
49135388Smjacob		if (dp->dom_family != sa->sa_family)
49235388Smjacob			continue;
49335388Smjacob
49435388Smjacob		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
49535388Smjacob			if (pr->pr_ctlinput)
49635388Smjacob				(*pr->pr_ctlinput)(cmd, sa, ctlparam);
49735388Smjacob	}
49835388Smjacob}
49935388Smjacob
50035388Smjacobstatic void
50135388Smjacobpfslowtimo(void *arg)
50235388Smjacob{
50335388Smjacob	struct domain *dp;
50435388Smjacob	struct protosw *pr;
50535388Smjacob
50635388Smjacob	for (dp = domains; dp; dp = dp->dom_next)
50735388Smjacob		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
50835388Smjacob			if (pr->pr_slowtimo)
50935388Smjacob				(*pr->pr_slowtimo)();
51035388Smjacob	callout_reset(&pfslow_callout, hz/2, pfslowtimo, NULL);
51135388Smjacob}
51235388Smjacob
51335388Smjacobstatic void
51435388Smjacobpffasttimo(void *arg)
51535388Smjacob{
51635388Smjacob	struct domain *dp;
51735388Smjacob	struct protosw *pr;
51835388Smjacob
51935388Smjacob	for (dp = domains; dp; dp = dp->dom_next)
52035388Smjacob		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
52135388Smjacob			if (pr->pr_fasttimo)
52235388Smjacob				(*pr->pr_fasttimo)();
52335388Smjacob	callout_reset(&pffast_callout, hz/5, pffasttimo, NULL);
52435388Smjacob}
52535388Smjacob