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