2014-12-02 22:45:58 +03:00
|
|
|
/* $NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $ */
|
1994-06-29 10:29:24 +04:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/*
|
1994-05-13 10:01:27 +04:00
|
|
|
* Copyright (c) 1982, 1986, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 20:26:28 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1993-03-21 12:45:37 +03:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
1998-03-01 05:20:01 +03:00
|
|
|
* @(#)uipc_domain.c 8.3 (Berkeley) 2/14/95
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
|
|
|
|
2001-11-12 18:25:01 +03:00
|
|
|
#include <sys/cdefs.h>
|
2014-12-02 22:45:58 +03:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $");
|
1998-07-05 04:51:04 +04:00
|
|
|
|
1993-12-18 07:21:37 +03:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/socket.h>
|
2005-03-09 08:07:19 +03:00
|
|
|
#include <sys/socketvar.h>
|
1993-12-18 07:21:37 +03:00
|
|
|
#include <sys/protosw.h>
|
|
|
|
#include <sys/domain.h>
|
|
|
|
#include <sys/mbuf.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/kernel.h>
|
1994-05-13 10:01:27 +04:00
|
|
|
#include <sys/systm.h>
|
2000-03-23 09:30:07 +03:00
|
|
|
#include <sys/callout.h>
|
2005-01-23 21:41:56 +03:00
|
|
|
#include <sys/queue.h>
|
1994-05-07 04:46:28 +04:00
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/sysctl.h>
|
2005-03-09 08:07:19 +03:00
|
|
|
#include <sys/un.h>
|
|
|
|
#include <sys/unpcb.h>
|
|
|
|
#include <sys/file.h>
|
2007-12-28 21:22:16 +03:00
|
|
|
#include <sys/filedesc.h>
|
2006-05-15 01:15:11 +04:00
|
|
|
#include <sys/kauth.h>
|
2014-12-02 22:45:58 +03:00
|
|
|
|
|
|
|
#include <netatalk/at.h>
|
|
|
|
#include <net/if_dl.h>
|
2013-01-31 18:30:47 +04:00
|
|
|
#include <netinet/in.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
MALLOC_DECLARE(M_SOCKADDR);
|
|
|
|
|
|
|
|
MALLOC_DEFINE(M_SOCKADDR, "sockaddr", "socket endpoints");
|
|
|
|
|
2004-03-23 16:22:03 +03:00
|
|
|
void pffasttimo(void *);
|
|
|
|
void pfslowtimo(void *);
|
1994-05-13 10:01:27 +04:00
|
|
|
|
2005-01-23 21:41:56 +03:00
|
|
|
struct domainhead domains = STAILQ_HEAD_INITIALIZER(domains);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
static struct domain *domain_array[AF_MAX];
|
2002-05-13 00:36:58 +04:00
|
|
|
|
2007-07-10 00:51:58 +04:00
|
|
|
callout_t pffasttimo_ch, pfslowtimo_ch;
|
2000-03-23 09:30:07 +03:00
|
|
|
|
1998-05-06 05:11:46 +04:00
|
|
|
/*
|
|
|
|
* Current time values for fast and slow timeouts. We can use u_int
|
|
|
|
* relatively safely. The fast timer will roll over in 27 years and
|
|
|
|
* the slow timer in 68 years.
|
|
|
|
*/
|
|
|
|
u_int pfslowtimo_now;
|
|
|
|
u_int pffasttimo_now;
|
|
|
|
|
2008-12-07 23:58:46 +03:00
|
|
|
static struct sysctllog *domain_sysctllog;
|
|
|
|
static void sysctl_net_setup(void);
|
|
|
|
|
2014-04-23 21:05:18 +04:00
|
|
|
/* ensure successful linkage even without any domains in link sets */
|
|
|
|
static struct domain domain_dummy;
|
|
|
|
__link_set_add_rodata(domains,domain_dummy);
|
|
|
|
|
1993-06-27 10:01:27 +04:00
|
|
|
void
|
2014-08-22 15:28:03 +04:00
|
|
|
domaininit(bool attach)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2005-01-23 21:41:56 +03:00
|
|
|
__link_set_decl(domains, struct domain);
|
|
|
|
struct domain * const * dpp;
|
|
|
|
struct domain *rt_domain = NULL;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2008-12-07 23:58:46 +03:00
|
|
|
sysctl_net_setup();
|
|
|
|
|
1999-07-01 12:12:45 +04:00
|
|
|
/*
|
2005-01-23 21:41:56 +03:00
|
|
|
* Add all of the domains. Make sure the PF_ROUTE
|
|
|
|
* domain is added last.
|
1999-07-01 12:12:45 +04:00
|
|
|
*/
|
2014-08-22 15:28:03 +04:00
|
|
|
if (attach) {
|
|
|
|
__link_set_foreach(dpp, domains) {
|
|
|
|
if (*dpp == &domain_dummy)
|
|
|
|
continue;
|
|
|
|
if ((*dpp)->dom_family == PF_ROUTE)
|
|
|
|
rt_domain = *dpp;
|
|
|
|
else
|
|
|
|
domain_attach(*dpp);
|
|
|
|
}
|
|
|
|
if (rt_domain)
|
|
|
|
domain_attach(rt_domain);
|
2005-01-23 21:41:56 +03:00
|
|
|
}
|
|
|
|
|
2008-04-24 15:38:36 +04:00
|
|
|
callout_init(&pffasttimo_ch, CALLOUT_MPSAFE);
|
|
|
|
callout_init(&pfslowtimo_ch, CALLOUT_MPSAFE);
|
2005-01-23 21:41:56 +03:00
|
|
|
|
|
|
|
callout_reset(&pffasttimo_ch, 1, pffasttimo, NULL);
|
|
|
|
callout_reset(&pfslowtimo_ch, 1, pfslowtimo, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
domain_attach(struct domain *dp)
|
|
|
|
{
|
|
|
|
const struct protosw *pr;
|
|
|
|
|
|
|
|
STAILQ_INSERT_TAIL(&domains, dp, dom_link);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
if (dp->dom_family < __arraycount(domain_array))
|
|
|
|
domain_array[dp->dom_family] = dp;
|
2005-01-23 21:41:56 +03:00
|
|
|
|
|
|
|
if (dp->dom_init)
|
|
|
|
(*dp->dom_init)();
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2003-02-26 09:31:08 +03:00
|
|
|
#ifdef MBUFTRACE
|
2005-01-23 21:41:56 +03:00
|
|
|
if (dp->dom_mowner.mo_name[0] == '\0') {
|
|
|
|
strncpy(dp->dom_mowner.mo_name, dp->dom_name,
|
|
|
|
sizeof(dp->dom_mowner.mo_name));
|
|
|
|
MOWNER_ATTACH(&dp->dom_mowner);
|
|
|
|
}
|
2003-02-26 09:31:08 +03:00
|
|
|
#endif
|
2005-01-23 21:41:56 +03:00
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
|
|
|
if (pr->pr_init)
|
|
|
|
(*pr->pr_init)();
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1996-08-14 09:43:35 +04:00
|
|
|
if (max_linkhdr < 16) /* XXX */
|
|
|
|
max_linkhdr = 16;
|
1993-03-21 12:45:37 +03:00
|
|
|
max_hdr = max_linkhdr + max_protohdr;
|
|
|
|
max_datalen = MHLEN - max_hdr;
|
|
|
|
}
|
|
|
|
|
2000-02-06 05:54:15 +03:00
|
|
|
struct domain *
|
2005-01-23 21:41:56 +03:00
|
|
|
pffinddomain(int family)
|
2000-02-06 05:54:15 +03:00
|
|
|
{
|
|
|
|
struct domain *dp;
|
|
|
|
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
if (family < __arraycount(domain_array) && domain_array[family] != NULL)
|
|
|
|
return domain_array[family];
|
|
|
|
|
2005-01-23 21:41:56 +03:00
|
|
|
DOMAIN_FOREACH(dp)
|
2000-02-06 05:54:15 +03:00
|
|
|
if (dp->dom_family == family)
|
2009-04-29 00:56:40 +04:00
|
|
|
return dp;
|
|
|
|
return NULL;
|
2000-02-06 05:54:15 +03:00
|
|
|
}
|
|
|
|
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *
|
2005-01-23 21:41:56 +03:00
|
|
|
pffindtype(int family, int type)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-02-06 05:54:15 +03:00
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
2000-02-06 05:54:15 +03:00
|
|
|
|
|
|
|
dp = pffinddomain(family);
|
|
|
|
if (dp == NULL)
|
2009-04-29 00:56:40 +04:00
|
|
|
return NULL;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
|
|
|
if (pr->pr_type && pr->pr_type == type)
|
2009-04-29 00:56:40 +04:00
|
|
|
return pr;
|
2000-02-06 05:54:15 +03:00
|
|
|
|
2009-04-29 00:56:40 +04:00
|
|
|
return NULL;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *
|
2005-01-23 21:41:56 +03:00
|
|
|
pffindproto(int family, int protocol, int type)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-02-06 05:54:15 +03:00
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
|
|
|
const struct protosw *maybe = NULL;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
if (family == 0)
|
2009-04-29 00:56:40 +04:00
|
|
|
return NULL;
|
2000-02-06 05:54:15 +03:00
|
|
|
|
|
|
|
dp = pffinddomain(family);
|
|
|
|
if (dp == NULL)
|
2009-04-29 00:56:40 +04:00
|
|
|
return NULL;
|
2000-02-06 05:54:15 +03:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
|
|
|
if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
|
2009-04-29 00:56:40 +04:00
|
|
|
return pr;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
|
2000-02-06 05:54:15 +03:00
|
|
|
pr->pr_protocol == 0 && maybe == NULL)
|
1993-03-21 12:45:37 +03:00
|
|
|
maybe = pr;
|
|
|
|
}
|
2009-04-29 00:56:40 +04:00
|
|
|
return maybe;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1) Introduce a new socket option, (SOL_SOCKET, SO_NOHEADER), that
tells a socket that it should both add a protocol header to tx'd
datagrams and remove the header from rx'd datagrams:
int onoff = 1, s = socket(...);
setsockopt(s, SOL_SOCKET, SO_NOHEADER, &onoff);
2) Add an implementation of (SOL_SOCKET, SO_NOHEADER) for raw IPv4
sockets.
3) Reorganize the protocols' pr_ctloutput implementations a bit.
Consistently return ENOPROTOOPT when an option is unsupported,
and EINVAL if a supported option's arguments are incorrect.
Reorganize the flow of code so that it's more clear how/when
options are passed down the stack until they are handled.
Shorten some pr_ctloutput staircases for readability.
4) Extract common mbuf code into subroutines, add new sockaddr
methods, and introduce a new subroutine, fsocreate(), for reuse
later; use it first in sys_socket():
struct mbuf *m_getsombuf(struct socket *so)
Create an mbuf and make its owner the socket `so'.
struct mbuf *m_intopt(struct socket *so, int val)
Create an mbuf, make its owner the socket `so', put the
int `val' into it, and set its length to sizeof(int).
int fsocreate(..., int *fd)
Create a socket, a la socreate(9), put the socket into the
given LWP's descriptor table, return the descriptor at `fd'
on success.
void *sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
const void *sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
Extract a pointer to the address part of a sockaddr. Write
the length of the address part at `slenp', if `slenp' is
not NULL.
socklen_t sockaddr_getlen(const struct sockaddr *sa)
Return the length of a sockaddr. This just evaluates to
sa->sa_len. I only add this for consistency with code that
appears in a portable userland library that I am going to
import.
const struct sockaddr *sockaddr_any(const struct sockaddr *sa)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
const void *sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
2007-09-19 08:33:42 +04:00
|
|
|
void *
|
|
|
|
sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
|
|
|
|
{
|
|
|
|
const struct domain *dom;
|
|
|
|
|
|
|
|
if ((dom = pffinddomain(sa->sa_family)) == NULL ||
|
|
|
|
dom->dom_sockaddr_addr == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return (*dom->dom_sockaddr_addr)(sa, slenp);
|
|
|
|
}
|
|
|
|
|
|
|
|
const void *
|
|
|
|
sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
|
|
|
|
{
|
|
|
|
const struct domain *dom;
|
2009-09-08 22:01:34 +04:00
|
|
|
|
1) Introduce a new socket option, (SOL_SOCKET, SO_NOHEADER), that
tells a socket that it should both add a protocol header to tx'd
datagrams and remove the header from rx'd datagrams:
int onoff = 1, s = socket(...);
setsockopt(s, SOL_SOCKET, SO_NOHEADER, &onoff);
2) Add an implementation of (SOL_SOCKET, SO_NOHEADER) for raw IPv4
sockets.
3) Reorganize the protocols' pr_ctloutput implementations a bit.
Consistently return ENOPROTOOPT when an option is unsupported,
and EINVAL if a supported option's arguments are incorrect.
Reorganize the flow of code so that it's more clear how/when
options are passed down the stack until they are handled.
Shorten some pr_ctloutput staircases for readability.
4) Extract common mbuf code into subroutines, add new sockaddr
methods, and introduce a new subroutine, fsocreate(), for reuse
later; use it first in sys_socket():
struct mbuf *m_getsombuf(struct socket *so)
Create an mbuf and make its owner the socket `so'.
struct mbuf *m_intopt(struct socket *so, int val)
Create an mbuf, make its owner the socket `so', put the
int `val' into it, and set its length to sizeof(int).
int fsocreate(..., int *fd)
Create a socket, a la socreate(9), put the socket into the
given LWP's descriptor table, return the descriptor at `fd'
on success.
void *sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
const void *sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
Extract a pointer to the address part of a sockaddr. Write
the length of the address part at `slenp', if `slenp' is
not NULL.
socklen_t sockaddr_getlen(const struct sockaddr *sa)
Return the length of a sockaddr. This just evaluates to
sa->sa_len. I only add this for consistency with code that
appears in a portable userland library that I am going to
import.
const struct sockaddr *sockaddr_any(const struct sockaddr *sa)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
const void *sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
2007-09-19 08:33:42 +04:00
|
|
|
if ((dom = pffinddomain(sa->sa_family)) == NULL ||
|
|
|
|
dom->dom_sockaddr_const_addr == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return (*dom->dom_sockaddr_const_addr)(sa, slenp);
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct sockaddr *
|
2009-04-29 00:54:50 +04:00
|
|
|
sockaddr_any_by_family(int family)
|
1) Introduce a new socket option, (SOL_SOCKET, SO_NOHEADER), that
tells a socket that it should both add a protocol header to tx'd
datagrams and remove the header from rx'd datagrams:
int onoff = 1, s = socket(...);
setsockopt(s, SOL_SOCKET, SO_NOHEADER, &onoff);
2) Add an implementation of (SOL_SOCKET, SO_NOHEADER) for raw IPv4
sockets.
3) Reorganize the protocols' pr_ctloutput implementations a bit.
Consistently return ENOPROTOOPT when an option is unsupported,
and EINVAL if a supported option's arguments are incorrect.
Reorganize the flow of code so that it's more clear how/when
options are passed down the stack until they are handled.
Shorten some pr_ctloutput staircases for readability.
4) Extract common mbuf code into subroutines, add new sockaddr
methods, and introduce a new subroutine, fsocreate(), for reuse
later; use it first in sys_socket():
struct mbuf *m_getsombuf(struct socket *so)
Create an mbuf and make its owner the socket `so'.
struct mbuf *m_intopt(struct socket *so, int val)
Create an mbuf, make its owner the socket `so', put the
int `val' into it, and set its length to sizeof(int).
int fsocreate(..., int *fd)
Create a socket, a la socreate(9), put the socket into the
given LWP's descriptor table, return the descriptor at `fd'
on success.
void *sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
const void *sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
Extract a pointer to the address part of a sockaddr. Write
the length of the address part at `slenp', if `slenp' is
not NULL.
socklen_t sockaddr_getlen(const struct sockaddr *sa)
Return the length of a sockaddr. This just evaluates to
sa->sa_len. I only add this for consistency with code that
appears in a portable userland library that I am going to
import.
const struct sockaddr *sockaddr_any(const struct sockaddr *sa)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
const void *sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
2007-09-19 08:33:42 +04:00
|
|
|
{
|
|
|
|
const struct domain *dom;
|
2009-09-08 22:01:34 +04:00
|
|
|
|
2009-04-29 00:54:50 +04:00
|
|
|
if ((dom = pffinddomain(family)) == NULL)
|
1) Introduce a new socket option, (SOL_SOCKET, SO_NOHEADER), that
tells a socket that it should both add a protocol header to tx'd
datagrams and remove the header from rx'd datagrams:
int onoff = 1, s = socket(...);
setsockopt(s, SOL_SOCKET, SO_NOHEADER, &onoff);
2) Add an implementation of (SOL_SOCKET, SO_NOHEADER) for raw IPv4
sockets.
3) Reorganize the protocols' pr_ctloutput implementations a bit.
Consistently return ENOPROTOOPT when an option is unsupported,
and EINVAL if a supported option's arguments are incorrect.
Reorganize the flow of code so that it's more clear how/when
options are passed down the stack until they are handled.
Shorten some pr_ctloutput staircases for readability.
4) Extract common mbuf code into subroutines, add new sockaddr
methods, and introduce a new subroutine, fsocreate(), for reuse
later; use it first in sys_socket():
struct mbuf *m_getsombuf(struct socket *so)
Create an mbuf and make its owner the socket `so'.
struct mbuf *m_intopt(struct socket *so, int val)
Create an mbuf, make its owner the socket `so', put the
int `val' into it, and set its length to sizeof(int).
int fsocreate(..., int *fd)
Create a socket, a la socreate(9), put the socket into the
given LWP's descriptor table, return the descriptor at `fd'
on success.
void *sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
const void *sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
Extract a pointer to the address part of a sockaddr. Write
the length of the address part at `slenp', if `slenp' is
not NULL.
socklen_t sockaddr_getlen(const struct sockaddr *sa)
Return the length of a sockaddr. This just evaluates to
sa->sa_len. I only add this for consistency with code that
appears in a portable userland library that I am going to
import.
const struct sockaddr *sockaddr_any(const struct sockaddr *sa)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
const void *sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
2007-09-19 08:33:42 +04:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return dom->dom_sa_any;
|
|
|
|
}
|
|
|
|
|
2009-04-29 00:54:50 +04:00
|
|
|
const struct sockaddr *
|
|
|
|
sockaddr_any(const struct sockaddr *sa)
|
|
|
|
{
|
|
|
|
return sockaddr_any_by_family(sa->sa_family);
|
|
|
|
}
|
|
|
|
|
1) Introduce a new socket option, (SOL_SOCKET, SO_NOHEADER), that
tells a socket that it should both add a protocol header to tx'd
datagrams and remove the header from rx'd datagrams:
int onoff = 1, s = socket(...);
setsockopt(s, SOL_SOCKET, SO_NOHEADER, &onoff);
2) Add an implementation of (SOL_SOCKET, SO_NOHEADER) for raw IPv4
sockets.
3) Reorganize the protocols' pr_ctloutput implementations a bit.
Consistently return ENOPROTOOPT when an option is unsupported,
and EINVAL if a supported option's arguments are incorrect.
Reorganize the flow of code so that it's more clear how/when
options are passed down the stack until they are handled.
Shorten some pr_ctloutput staircases for readability.
4) Extract common mbuf code into subroutines, add new sockaddr
methods, and introduce a new subroutine, fsocreate(), for reuse
later; use it first in sys_socket():
struct mbuf *m_getsombuf(struct socket *so)
Create an mbuf and make its owner the socket `so'.
struct mbuf *m_intopt(struct socket *so, int val)
Create an mbuf, make its owner the socket `so', put the
int `val' into it, and set its length to sizeof(int).
int fsocreate(..., int *fd)
Create a socket, a la socreate(9), put the socket into the
given LWP's descriptor table, return the descriptor at `fd'
on success.
void *sockaddr_addr(struct sockaddr *sa, socklen_t *slenp)
const void *sockaddr_const_addr(const struct sockaddr *sa, socklen_t *slenp)
Extract a pointer to the address part of a sockaddr. Write
the length of the address part at `slenp', if `slenp' is
not NULL.
socklen_t sockaddr_getlen(const struct sockaddr *sa)
Return the length of a sockaddr. This just evaluates to
sa->sa_len. I only add this for consistency with code that
appears in a portable userland library that I am going to
import.
const struct sockaddr *sockaddr_any(const struct sockaddr *sa)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
const void *sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
Return the "don't care" sockaddr in the same family as
`sa'. This is the address a client should sobind(9) if it
does not care the source address and, if applicable, the
port et cetera that it uses.
2007-09-19 08:33:42 +04:00
|
|
|
const void *
|
|
|
|
sockaddr_anyaddr(const struct sockaddr *sa, socklen_t *slenp)
|
|
|
|
{
|
|
|
|
const struct sockaddr *any;
|
|
|
|
|
|
|
|
if ((any = sockaddr_any(sa)) == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return sockaddr_const_addr(any, slenp);
|
|
|
|
}
|
|
|
|
|
2014-12-02 22:45:58 +03:00
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
static void
|
|
|
|
sockaddr_checklen(const struct sockaddr *sa)
|
|
|
|
{
|
|
|
|
socklen_t len = 0;
|
|
|
|
switch (sa->sa_family) {
|
|
|
|
case AF_INET:
|
|
|
|
len = sizeof(struct sockaddr_in);
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
len = sizeof(struct sockaddr_in6);
|
|
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
|
|
len = sizeof(struct sockaddr_un);
|
|
|
|
break;
|
|
|
|
case AF_LINK:
|
|
|
|
len = sizeof(struct sockaddr_dl);
|
|
|
|
// As long as it is not 0...
|
|
|
|
if (sa->sa_len != 0)
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
case AF_APPLETALK:
|
|
|
|
len = sizeof(struct sockaddr_at);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("%s: Unhandled af=%hhu socklen=%hhu\n", __func__,
|
|
|
|
sa->sa_family, sa->sa_len);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (len != sa->sa_len) {
|
|
|
|
char buf[512];
|
|
|
|
sockaddr_format(sa, buf, sizeof(buf));
|
|
|
|
printf("%s: %p bad len af=%hhu socklen=%hhu len=%u [%s]\n",
|
|
|
|
__func__, sa, sa->sa_family, sa->sa_len,
|
|
|
|
(unsigned)len, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define sockaddr_checklen(sa) ((void)0)
|
|
|
|
#endif
|
|
|
|
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
struct sockaddr *
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
sockaddr_alloc(sa_family_t af, socklen_t socklen, int flags)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
{
|
|
|
|
struct sockaddr *sa;
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
socklen_t reallen = MAX(socklen, offsetof(struct sockaddr, sa_data[0]));
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
if ((sa = malloc(reallen, M_SOCKADDR, flags)) == NULL)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
sa->sa_family = af;
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
sa->sa_len = reallen;
|
2014-12-02 22:45:58 +03:00
|
|
|
sockaddr_checklen(sa);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
return sa;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sockaddr *
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
sockaddr_copy(struct sockaddr *dst, socklen_t socklen,
|
|
|
|
const struct sockaddr *src)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
{
|
2007-09-01 10:50:44 +04:00
|
|
|
if (__predict_false(socklen < src->sa_len)) {
|
|
|
|
panic("%s: source too long, %d < %d bytes", __func__, socklen,
|
|
|
|
src->sa_len);
|
|
|
|
}
|
2014-12-02 22:45:58 +03:00
|
|
|
sockaddr_checklen(src);
|
2007-09-01 10:50:44 +04:00
|
|
|
return memcpy(dst, src, src->sa_len);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
}
|
|
|
|
|
Make ifconfig(8) set and display preference numbers for IPv6
addresses. Make the kernel support SIOC[SG]IFADDRPREF for IPv6
interface addresses.
In in6ifa_ifpforlinklocal(), consult preference numbers before
making an otherwise arbitrary choice of in6_ifaddr. Otherwise,
preference numbers are *not* consulted by the kernel, but that will
be rather easy for somebody with a little bit of free time to fix.
Please note that setting the preference number for a link-local
IPv6 address does not work right, yet, but that ought to be fixed
soon.
In support of the changes above,
1 Add a method to struct domain for "externalizing" a sockaddr, and
provide an implementation for IPv6. Expect more work in this area: it
may be more proper to say that the IPv6 implementation "internalizes"
a sockaddr. Add sockaddr_externalize().
2 Add a subroutine, sofamily(), that returns a struct socket's address
family or AF_UNSPEC.
3 Make a lot of IPv4-specific code generic, and move it from
sys/netinet/ to sys/net/ for re-use by IPv6 parts of the kernel and
ifconfig(8).
2009-09-12 02:06:29 +04:00
|
|
|
struct sockaddr *
|
|
|
|
sockaddr_externalize(struct sockaddr *dst, socklen_t socklen,
|
|
|
|
const struct sockaddr *src)
|
|
|
|
{
|
|
|
|
struct domain *dom;
|
|
|
|
|
|
|
|
dom = pffinddomain(src->sa_family);
|
|
|
|
|
|
|
|
if (dom != NULL && dom->dom_sockaddr_externalize != NULL)
|
|
|
|
return (*dom->dom_sockaddr_externalize)(dst, socklen, src);
|
|
|
|
|
|
|
|
return sockaddr_copy(dst, socklen, src);
|
|
|
|
}
|
|
|
|
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
int
|
|
|
|
sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
|
|
|
|
{
|
2007-05-06 06:56:37 +04:00
|
|
|
int len, rc;
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
struct domain *dom;
|
|
|
|
|
|
|
|
if (sa1->sa_family != sa2->sa_family)
|
|
|
|
return sa1->sa_family - sa2->sa_family;
|
|
|
|
|
2007-05-06 06:56:37 +04:00
|
|
|
dom = pffinddomain(sa1->sa_family);
|
|
|
|
|
|
|
|
if (dom != NULL && dom->dom_sockaddr_cmp != NULL)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
return (*dom->dom_sockaddr_cmp)(sa1, sa2);
|
|
|
|
|
2007-05-06 06:56:37 +04:00
|
|
|
len = MIN(sa1->sa_len, sa2->sa_len);
|
|
|
|
|
|
|
|
if (dom == NULL || dom->dom_sa_cmplen == 0) {
|
|
|
|
if ((rc = memcmp(sa1, sa2, len)) != 0)
|
|
|
|
return rc;
|
|
|
|
return sa1->sa_len - sa2->sa_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rc = memcmp((const char *)sa1 + dom->dom_sa_cmpofs,
|
|
|
|
(const char *)sa2 + dom->dom_sa_cmpofs,
|
|
|
|
MIN(dom->dom_sa_cmplen,
|
|
|
|
len - MIN(len, dom->dom_sa_cmpofs)))) != 0)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
return rc;
|
|
|
|
|
2007-05-06 06:56:37 +04:00
|
|
|
return MIN(dom->dom_sa_cmplen + dom->dom_sa_cmpofs, sa1->sa_len) -
|
|
|
|
MIN(dom->dom_sa_cmplen + dom->dom_sa_cmpofs, sa2->sa_len);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
struct sockaddr *
|
|
|
|
sockaddr_dup(const struct sockaddr *src, int flags)
|
|
|
|
{
|
|
|
|
struct sockaddr *dst;
|
|
|
|
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
if ((dst = sockaddr_alloc(src->sa_family, src->sa_len, flags)) == NULL)
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
return NULL;
|
|
|
|
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
return sockaddr_copy(dst, dst->sa_len, src);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sockaddr_free(struct sockaddr *sa)
|
|
|
|
{
|
Use malloc(9) for sockaddrs instead of pool(9), and remove dom_sa_pool
and dom_sa_len members from struct domain. Pools of fixed-size
objects are too rigid for sockaddr_dls, whose size can vary over
a wide range.
Return sockaddr_dl to its "historical" size. Now that I'm using
malloc(9) instead of pool(9) to allocate sockaddr_dl, I can create
a sockaddr_dl of any size in the kernel, so expanding sockaddr_dl
is useless.
Avoid using sizeof(struct sockaddr_dl) in the kernel.
Introduce sockaddr_dl_alloc() for allocating & initializing an
arbitrary sockaddr_dl on the heap.
Add an argument, the sockaddr length, to sockaddr_alloc(),
sockaddr_copy(), and sockaddr_dl_setaddr().
Constify: LLADDR() -> CLLADDR().
Where the kernel overwrites LLADDR(), use sockaddr_dl_setaddr(),
instead. Used properly, sockaddr_dl_setaddr() will not overrun
the end of the sockaddr.
2007-08-30 06:17:34 +04:00
|
|
|
free(sa, M_SOCKADDR);
|
Eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct
route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is
necessary for correct routing. Route-cache invalidation fixes an
ancient PR, kern/3508, at long last; it fixes various other PRs,
also.
Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are
mine.
DETAILS
1 I added to each address family a pool of sockaddrs. I have
introduced routines for allocating, copying, and duplicating,
and freeing sockaddrs:
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
void sockaddr_free(struct sockaddr *sa);
sockaddr_alloc() returns either a sockaddr from the pool belonging
to the specified family, or NULL if the pool is exhausted. The
returned sockaddr has the right size for that family; sa_family
and sa_len fields are initialized to the family and sockaddr
length---e.g., sa_family = AF_INET and sa_len = sizeof(struct
sockaddr_in). sockaddr_free() puts the given sockaddr back into
its family's pool.
sockaddr_dup() and sockaddr_copy() work analogously to strdup()
and strcpy(), respectively. sockaddr_copy() KASSERTs that the
family of the destination and source sockaddrs are alike.
The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is
passed directly to pool_get(9).
2 I added routines for initializing sockaddrs in each address
family, sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(),
etc. They are fairly self-explanatory.
3 structs route_in6 and route_iso are no more. All protocol families
use struct route. I have changed the route cache, 'struct route',
so that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:
int rtcache_setdst(struct route *, const struct sockaddr *);
rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.
It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL
everywhere in the kernel.
4 Each routing domain (struct domain) has a list of live route
caches, dom_rtcache. rtflushall(sa_family_t af) looks up the
domain indicated by 'af', walks the domain's list of route caches
and invalidates each one.
2007-05-03 00:40:22 +04:00
|
|
|
}
|
|
|
|
|
2014-12-02 22:45:58 +03:00
|
|
|
static int
|
|
|
|
sun_print(char *buf, size_t len, const void *v)
|
|
|
|
{
|
|
|
|
const struct sockaddr_un *sun = v;
|
|
|
|
return snprintf(buf, len, "%s", sun->sun_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2013-01-31 18:30:47 +04:00
|
|
|
sockaddr_format(const struct sockaddr *sa, char *buf, size_t len)
|
|
|
|
{
|
2014-12-02 22:45:58 +03:00
|
|
|
size_t plen = 0;
|
|
|
|
|
|
|
|
if (sa == NULL)
|
|
|
|
return strlcpy(buf, "(null)", len);
|
2013-01-31 18:30:47 +04:00
|
|
|
|
|
|
|
switch (sa->sa_family) {
|
|
|
|
case AF_LOCAL:
|
2014-12-02 22:45:58 +03:00
|
|
|
plen = strlcpy(buf, "unix: ", len);
|
|
|
|
break;
|
2013-01-31 18:30:47 +04:00
|
|
|
case AF_INET:
|
2014-12-02 22:45:58 +03:00
|
|
|
plen = strlcpy(buf, "inet: ", len);
|
2013-01-31 18:30:47 +04:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2014-12-02 22:45:58 +03:00
|
|
|
plen = strlcpy(buf, "inet6: ", len);
|
2013-01-31 18:30:47 +04:00
|
|
|
break;
|
2014-12-02 22:45:58 +03:00
|
|
|
case AF_LINK:
|
|
|
|
plen = strlcpy(buf, "link: ", len);
|
|
|
|
break;
|
|
|
|
case AF_APPLETALK:
|
|
|
|
plen = strlcpy(buf, "atalk: ", len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return snprintf(buf, len, "(unknown socket family %d)",
|
|
|
|
(int)sa->sa_family);
|
2013-01-31 18:30:47 +04:00
|
|
|
}
|
2014-12-02 22:45:58 +03:00
|
|
|
|
|
|
|
buf += plen;
|
|
|
|
if (plen > len)
|
|
|
|
len = 0;
|
|
|
|
else
|
|
|
|
len -= plen;
|
|
|
|
|
|
|
|
switch (sa->sa_family) {
|
|
|
|
case AF_LOCAL:
|
|
|
|
return sun_print(buf, len, sa);
|
|
|
|
case AF_INET:
|
|
|
|
return sin_print(buf, len, sa);
|
|
|
|
case AF_INET6:
|
|
|
|
return sin6_print(buf, len, sa);
|
|
|
|
case AF_LINK:
|
|
|
|
return sdl_print(buf, len, sa);
|
|
|
|
case AF_APPLETALK:
|
|
|
|
return sat_print(buf, len, sa);
|
|
|
|
default:
|
|
|
|
panic("bad family %hhu", sa->sa_family);
|
2013-01-31 18:30:47 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-09 08:07:19 +03:00
|
|
|
/*
|
|
|
|
* sysctl helper to stuff PF_LOCAL pcbs into sysctl structures
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
sysctl_dounpcb(struct kinfo_pcb *pcb, const struct socket *so)
|
|
|
|
{
|
|
|
|
struct unpcb *unp = sotounpcb(so);
|
|
|
|
struct sockaddr_un *un = unp->unp_addr;
|
|
|
|
|
|
|
|
memset(pcb, 0, sizeof(*pcb));
|
|
|
|
|
|
|
|
pcb->ki_family = so->so_proto->pr_domain->dom_family;
|
|
|
|
pcb->ki_type = so->so_proto->pr_type;
|
|
|
|
pcb->ki_protocol = so->so_proto->pr_protocol;
|
|
|
|
pcb->ki_pflags = unp->unp_flags;
|
|
|
|
|
|
|
|
pcb->ki_pcbaddr = PTRTOUINT64(unp);
|
|
|
|
/* pcb->ki_ppcbaddr = unp has no ppcb... */
|
|
|
|
pcb->ki_sockaddr = PTRTOUINT64(so);
|
|
|
|
|
|
|
|
pcb->ki_sostate = so->so_state;
|
|
|
|
/* pcb->ki_prstate = unp has no state... */
|
|
|
|
|
|
|
|
pcb->ki_rcvq = so->so_rcv.sb_cc;
|
|
|
|
pcb->ki_sndq = so->so_snd.sb_cc;
|
|
|
|
|
2014-04-17 20:14:22 +04:00
|
|
|
un = (struct sockaddr_un *)pcb->ki_spad;
|
2005-03-09 08:07:19 +03:00
|
|
|
/*
|
|
|
|
* local domain sockets may bind without having a local
|
|
|
|
* endpoint. bleah!
|
|
|
|
*/
|
|
|
|
if (unp->unp_addr != NULL) {
|
2014-04-02 19:35:45 +04:00
|
|
|
/*
|
|
|
|
* We've added one to sun_len when allocating to
|
|
|
|
* hold terminating NUL which we want here. See
|
|
|
|
* makeun().
|
|
|
|
*/
|
|
|
|
memcpy(un, unp->unp_addr,
|
2014-04-17 20:14:22 +04:00
|
|
|
min(sizeof(pcb->ki_spad), unp->unp_addr->sun_len + 1));
|
2005-03-09 08:07:19 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
un->sun_len = offsetof(struct sockaddr_un, sun_path);
|
|
|
|
un->sun_family = pcb->ki_family;
|
|
|
|
}
|
|
|
|
if (unp->unp_conn != NULL) {
|
2014-04-17 20:14:22 +04:00
|
|
|
un = (struct sockaddr_un *)pcb->ki_dpad;
|
2005-03-09 08:07:19 +03:00
|
|
|
if (unp->unp_conn->unp_addr != NULL) {
|
2014-04-02 19:35:45 +04:00
|
|
|
memcpy(un, unp->unp_conn->unp_addr,
|
2014-04-17 20:14:22 +04:00
|
|
|
min(sizeof(pcb->ki_dpad), unp->unp_conn->unp_addr->sun_len + 1));
|
2005-03-09 08:07:19 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
un->sun_len = offsetof(struct sockaddr_un, sun_path);
|
|
|
|
un->sun_family = pcb->ki_family;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pcb->ki_inode = unp->unp_ino;
|
|
|
|
pcb->ki_vnode = PTRTOUINT64(unp->unp_vnode);
|
|
|
|
pcb->ki_conn = PTRTOUINT64(unp->unp_conn);
|
|
|
|
pcb->ki_refs = PTRTOUINT64(unp->unp_refs);
|
|
|
|
pcb->ki_nextref = PTRTOUINT64(unp->unp_nextref);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sysctl_unpcblist(SYSCTLFN_ARGS)
|
|
|
|
{
|
2013-09-15 19:37:27 +04:00
|
|
|
struct file *fp, *dfp;
|
2005-03-09 08:07:19 +03:00
|
|
|
struct socket *so;
|
|
|
|
struct kinfo_pcb pcb;
|
|
|
|
char *dp;
|
|
|
|
size_t len, needed, elem_size, out_size;
|
2013-09-15 19:37:27 +04:00
|
|
|
int error, elem_count, pf, type;
|
2005-03-09 08:07:19 +03:00
|
|
|
|
|
|
|
if (namelen == 1 && name[0] == CTL_QUERY)
|
2009-04-29 00:56:40 +04:00
|
|
|
return sysctl_query(SYSCTLFN_CALL(rnode));
|
2005-03-09 08:07:19 +03:00
|
|
|
|
|
|
|
if (namelen != 4)
|
2009-04-29 00:56:40 +04:00
|
|
|
return EINVAL;
|
2005-03-09 08:07:19 +03:00
|
|
|
|
2006-04-15 08:41:52 +04:00
|
|
|
if (oldp != NULL) {
|
|
|
|
len = *oldlenp;
|
|
|
|
elem_size = name[2];
|
|
|
|
elem_count = name[3];
|
|
|
|
if (elem_size != sizeof(pcb))
|
|
|
|
return EINVAL;
|
|
|
|
} else {
|
|
|
|
len = 0;
|
|
|
|
elem_size = sizeof(pcb);
|
|
|
|
elem_count = INT_MAX;
|
|
|
|
}
|
2005-03-09 08:07:19 +03:00
|
|
|
error = 0;
|
|
|
|
dp = oldp;
|
2006-04-15 08:41:52 +04:00
|
|
|
out_size = elem_size;
|
2005-03-09 08:07:19 +03:00
|
|
|
needed = 0;
|
|
|
|
|
|
|
|
if (name - oname != 4)
|
2009-04-29 00:56:40 +04:00
|
|
|
return EINVAL;
|
2005-03-09 08:07:19 +03:00
|
|
|
|
|
|
|
pf = oname[1];
|
|
|
|
type = oname[2];
|
|
|
|
|
2008-01-07 19:12:52 +03:00
|
|
|
/*
|
|
|
|
* allocate dummy file descriptor to make position in list.
|
|
|
|
*/
|
|
|
|
sysctl_unlock();
|
|
|
|
if ((dfp = fgetdummy()) == NULL) {
|
|
|
|
sysctl_relock();
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
|
|
|
|
2005-03-09 08:07:19 +03:00
|
|
|
/*
|
|
|
|
* there's no "list" of local domain sockets, so we have
|
|
|
|
* to walk the file list looking for them. :-/
|
|
|
|
*/
|
2007-12-28 21:22:16 +03:00
|
|
|
mutex_enter(&filelist_lock);
|
2005-03-09 08:07:19 +03:00
|
|
|
LIST_FOREACH(fp, &filehead, f_list) {
|
2008-01-07 19:12:52 +03:00
|
|
|
if (fp->f_count == 0 || fp->f_type != DTYPE_SOCKET ||
|
2014-09-05 13:20:59 +04:00
|
|
|
fp->f_socket == NULL)
|
2008-01-07 19:12:52 +03:00
|
|
|
continue;
|
2014-09-05 13:20:59 +04:00
|
|
|
so = fp->f_socket;
|
2005-03-09 08:07:19 +03:00
|
|
|
if (so->so_type != type)
|
|
|
|
continue;
|
|
|
|
if (so->so_proto->pr_domain->dom_family != pf)
|
|
|
|
continue;
|
2009-10-04 00:24:39 +04:00
|
|
|
if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
|
|
|
|
KAUTH_REQ_NETWORK_SOCKET_CANSEE, so, NULL, NULL) != 0)
|
|
|
|
continue;
|
2005-03-09 08:07:19 +03:00
|
|
|
if (len >= elem_size && elem_count > 0) {
|
2008-03-22 00:54:58 +03:00
|
|
|
mutex_enter(&fp->f_lock);
|
|
|
|
fp->f_count++;
|
|
|
|
mutex_exit(&fp->f_lock);
|
2008-01-07 19:12:52 +03:00
|
|
|
LIST_INSERT_AFTER(fp, dfp, f_list);
|
2007-12-28 21:22:16 +03:00
|
|
|
mutex_exit(&filelist_lock);
|
2005-03-09 08:07:19 +03:00
|
|
|
sysctl_dounpcb(&pcb, so);
|
|
|
|
error = copyout(&pcb, dp, out_size);
|
2008-03-22 00:54:58 +03:00
|
|
|
closef(fp);
|
2007-12-28 21:22:16 +03:00
|
|
|
mutex_enter(&filelist_lock);
|
2008-01-07 19:12:52 +03:00
|
|
|
LIST_REMOVE(dfp, f_list);
|
2005-03-09 08:07:19 +03:00
|
|
|
if (error)
|
|
|
|
break;
|
|
|
|
dp += elem_size;
|
|
|
|
len -= elem_size;
|
|
|
|
}
|
2009-03-11 08:55:22 +03:00
|
|
|
needed += elem_size;
|
|
|
|
if (elem_count > 0 && elem_count != INT_MAX)
|
|
|
|
elem_count--;
|
2005-03-09 08:07:19 +03:00
|
|
|
}
|
2007-12-28 21:22:16 +03:00
|
|
|
mutex_exit(&filelist_lock);
|
2008-01-07 19:12:52 +03:00
|
|
|
fputdummy(dfp);
|
|
|
|
*oldlenp = needed;
|
2005-03-09 08:07:19 +03:00
|
|
|
if (oldp == NULL)
|
|
|
|
*oldlenp += PCB_SLOP * sizeof(struct kinfo_pcb);
|
2008-01-07 19:12:52 +03:00
|
|
|
sysctl_relock();
|
2005-03-09 08:07:19 +03:00
|
|
|
|
2009-04-29 00:56:40 +04:00
|
|
|
return error;
|
2005-03-09 08:07:19 +03:00
|
|
|
}
|
|
|
|
|
2008-12-07 23:58:46 +03:00
|
|
|
static void
|
2009-03-15 20:14:40 +03:00
|
|
|
sysctl_net_setup(void)
|
1994-05-07 04:46:28 +04:00
|
|
|
{
|
2008-12-07 23:58:46 +03:00
|
|
|
|
|
|
|
KASSERT(domain_sysctllog == NULL);
|
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
2004-03-24 18:34:46 +03:00
|
|
|
CTLFLAG_PERMANENT,
|
2004-05-25 08:33:59 +04:00
|
|
|
CTLTYPE_NODE, "local",
|
|
|
|
SYSCTL_DESCR("PF_LOCAL related settings"),
|
Dynamic sysctl.
Gone are the old kern_sysctl(), cpu_sysctl(), hw_sysctl(),
vfs_sysctl(), etc, routines, along with sysctl_int() et al. Now all
nodes are registered with the tree, and nodes can be added (or
removed) easily, and I/O to and from the tree is handled generically.
Since the nodes are registered with the tree, the mapping from name to
number (and back again) can now be discovered, instead of having to be
hard coded. Adding new nodes to the tree is likewise much simpler --
the new infrastructure handles almost all the work for simple types,
and just about anything else can be done with a small helper function.
All existing nodes are where they were before (numerically speaking),
so all existing consumers of sysctl information should notice no
difference.
PS - I'm sorry, but there's a distinct lack of documentation at the
moment. I'm working on sysctl(3/8/9) right now, and I promise to
watch out for buses.
2003-12-04 22:38:21 +03:00
|
|
|
NULL, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, CTL_EOL);
|
2008-12-07 23:58:46 +03:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
2005-03-09 08:07:19 +03:00
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_NODE, "stream",
|
|
|
|
SYSCTL_DESCR("SOCK_STREAM settings"),
|
|
|
|
NULL, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_STREAM, CTL_EOL);
|
2011-05-29 07:32:46 +04:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_NODE, "seqpacket",
|
|
|
|
SYSCTL_DESCR("SOCK_SEQPACKET settings"),
|
|
|
|
NULL, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_SEQPACKET, CTL_EOL);
|
2008-12-07 23:58:46 +03:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
2005-03-09 08:07:19 +03:00
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_NODE, "dgram",
|
|
|
|
SYSCTL_DESCR("SOCK_DGRAM settings"),
|
|
|
|
NULL, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_DGRAM, CTL_EOL);
|
1994-05-07 04:46:28 +04:00
|
|
|
|
2008-12-07 23:58:46 +03:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
2005-03-09 08:07:19 +03:00
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_STRUCT, "pcblist",
|
|
|
|
SYSCTL_DESCR("SOCK_STREAM protocol control block list"),
|
|
|
|
sysctl_unpcblist, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_STREAM, CTL_CREATE, CTL_EOL);
|
2011-05-29 07:32:46 +04:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_STRUCT, "pcblist",
|
|
|
|
SYSCTL_DESCR("SOCK_SEQPACKET protocol control "
|
|
|
|
"block list"),
|
|
|
|
sysctl_unpcblist, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_SEQPACKET, CTL_CREATE, CTL_EOL);
|
2008-12-07 23:58:46 +03:00
|
|
|
sysctl_createv(&domain_sysctllog, 0, NULL, NULL,
|
2005-03-09 08:07:19 +03:00
|
|
|
CTLFLAG_PERMANENT,
|
|
|
|
CTLTYPE_STRUCT, "pcblist",
|
|
|
|
SYSCTL_DESCR("SOCK_DGRAM protocol control block list"),
|
|
|
|
sysctl_unpcblist, 0, NULL, 0,
|
|
|
|
CTL_NET, PF_LOCAL, SOCK_DGRAM, CTL_CREATE, CTL_EOL);
|
1994-05-07 04:46:28 +04:00
|
|
|
}
|
|
|
|
|
1993-06-27 10:01:27 +04:00
|
|
|
void
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
pfctlinput(int cmd, const struct sockaddr *sa)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
DOMAIN_FOREACH(dp) {
|
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
|
|
|
if (pr->pr_ctlinput != NULL)
|
1996-02-04 05:17:43 +03:00
|
|
|
(*pr->pr_ctlinput)(cmd, sa, NULL);
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
}
|
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2001-02-11 09:38:45 +03:00
|
|
|
void
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
pfctlinput2(int cmd, const struct sockaddr *sa, void *ctlparam)
|
2001-02-11 09:38:45 +03:00
|
|
|
{
|
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
2001-02-11 09:38:45 +03:00
|
|
|
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
if (sa == NULL)
|
2001-02-11 09:38:45 +03:00
|
|
|
return;
|
2005-01-23 21:41:56 +03:00
|
|
|
|
|
|
|
DOMAIN_FOREACH(dp) {
|
2001-02-11 09:38:45 +03:00
|
|
|
/*
|
|
|
|
* the check must be made by xx_ctlinput() anyways, to
|
|
|
|
* make sure we use data item pointed to by ctlparam in
|
|
|
|
* correct way. the following check is made just for safety.
|
|
|
|
*/
|
|
|
|
if (dp->dom_family != sa->sa_family)
|
|
|
|
continue;
|
|
|
|
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
|
|
|
if (pr->pr_ctlinput != NULL)
|
2001-02-11 09:38:45 +03:00
|
|
|
(*pr->pr_ctlinput)(cmd, sa, ctlparam);
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
}
|
2001-02-11 09:38:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1993-06-27 10:01:27 +04:00
|
|
|
void
|
2006-11-01 13:17:58 +03:00
|
|
|
pfslowtimo(void *arg)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1998-05-06 05:11:46 +04:00
|
|
|
pfslowtimo_now++;
|
|
|
|
|
2005-01-23 21:41:56 +03:00
|
|
|
DOMAIN_FOREACH(dp) {
|
1993-03-21 12:45:37 +03:00
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
|
|
|
if (pr->pr_slowtimo)
|
|
|
|
(*pr->pr_slowtimo)();
|
2005-01-23 21:41:56 +03:00
|
|
|
}
|
2011-10-28 01:10:55 +04:00
|
|
|
callout_schedule(&pfslowtimo_ch, hz / PR_SLOWHZ);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1993-06-27 10:01:27 +04:00
|
|
|
void
|
2006-11-01 13:17:58 +03:00
|
|
|
pffasttimo(void *arg)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct domain *dp;
|
2004-04-22 05:01:40 +04:00
|
|
|
const struct protosw *pr;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1998-05-06 05:11:46 +04:00
|
|
|
pffasttimo_now++;
|
|
|
|
|
2005-01-23 21:41:56 +03:00
|
|
|
DOMAIN_FOREACH(dp) {
|
1993-03-21 12:45:37 +03:00
|
|
|
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
|
|
|
if (pr->pr_fasttimo)
|
|
|
|
(*pr->pr_fasttimo)();
|
2005-01-23 21:41:56 +03:00
|
|
|
}
|
2011-10-28 01:10:55 +04:00
|
|
|
callout_schedule(&pffasttimo_ch, hz / PR_FASTHZ);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|