Merge ^/head r364264 through r364278.
This commit is contained in:
commit
e81829d0e5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang1100-import/; revision=364279
@ -5,6 +5,7 @@
|
||||
SUBDIR= cap_dns
|
||||
SUBDIR+= cap_fileargs
|
||||
SUBDIR+= cap_grp
|
||||
SUBDIR+= cap_net
|
||||
SUBDIR+= cap_pwd
|
||||
SUBDIR+= cap_sysctl
|
||||
SUBDIR+= cap_syslog
|
||||
|
@ -27,11 +27,6 @@ SUBDIR.${MK_TESTS}+= tests
|
||||
MAN+= cap_dns.3
|
||||
|
||||
MLINKS+=cap_dns.3 libcap_dns.3
|
||||
MLINKS+=cap_dns.3 cap_gethostbyname.3
|
||||
MLINKS+=cap_dns.3 cap_gethostbyname2.3
|
||||
MLINKS+=cap_dns.3 cap_gethostbyaddr.3
|
||||
MLINKS+=cap_dns.3 cap_getaddrinfo.3
|
||||
MLINKS+=cap_dns.3 cap_getnameinfo.3
|
||||
MLINKS+=cap_dns.3 cap_dns_type_limit.3
|
||||
MLINKS+=cap_dns.3 cap_dns_family_limit.3
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 5, 2020
|
||||
.Dd August 15, 2020
|
||||
.Dt CAP_DNS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -58,6 +58,9 @@
|
||||
.Fn cap_dns_family_limit "const cap_channel_t *chan" "const int *families" "size_t nfamilies"
|
||||
.Sh DESCRIPTION
|
||||
.Bf -symbolic
|
||||
This service is obsolete and
|
||||
.Xr cap_net 3
|
||||
should be used instead.
|
||||
The
|
||||
.Fn cap_getaddrinfo ,
|
||||
and
|
||||
|
48
lib/libcasper/services/cap_net/Makefile
Normal file
48
lib/libcasper/services/cap_net/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SHLIBDIR?= /lib/casper
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=libcasper
|
||||
|
||||
SHLIB_MAJOR= 1
|
||||
INCSDIR?= ${INCLUDEDIR}/casper
|
||||
|
||||
.if ${MK_CASPER} != "no"
|
||||
SHLIB= cap_net
|
||||
|
||||
SRCS= cap_net.c
|
||||
.endif
|
||||
|
||||
INCS= cap_net.h
|
||||
|
||||
LIBADD= nv
|
||||
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
CFLAGS+=-DWITH_CASPER
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
MAN+= cap_net.3
|
||||
|
||||
MLINKS+=cap_net.3 libcap_net.3
|
||||
MLINKS+=cap_net.3 cap_bind.3
|
||||
MLINKS+=cap_net.3 cap_connect.3
|
||||
MLINKS+=cap_net.3 cap_net_free.3
|
||||
MLINKS+=cap_net.3 cap_net_limit.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_addr2name.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_addr2name_family.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_bind.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_connect.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_init.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_name2addr.3
|
||||
MLINKS+=cap_net.3 cap_net_limit_name2addr_family.3
|
||||
MLINKS+=cap_net.3 cap_getaddrinfo.3
|
||||
MLINKS+=cap_net.3 cap_gethostbyaddr.3
|
||||
MLINKS+=cap_net.3 cap_gethostbyname.3
|
||||
MLINKS+=cap_net.3 cap_gethostbyname2.3
|
||||
MLINKS+=cap_net.3 cap_getnameinfo.3
|
||||
|
||||
.include <bsd.lib.mk>
|
287
lib/libcasper/services/cap_net/cap_net.3
Normal file
287
lib/libcasper/services/cap_net/cap_net.3
Normal file
@ -0,0 +1,287 @@
|
||||
.\" Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 15, 2020
|
||||
.Dt CAP_NET 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cap_bind ,
|
||||
.Nm cap_connect ,
|
||||
.Nm cap_getaddrinfo ,
|
||||
.Nm cap_gethostbyaddr ,
|
||||
.Nm cap_gethostbyname ,
|
||||
.Nm cap_gethostbyname2 ,
|
||||
.Nm cap_getnameinfo ,
|
||||
.Nm cap_net_free ,
|
||||
.Nm cap_net_limit ,
|
||||
.Nm cap_net_limit_addr2name ,
|
||||
.Nm cap_net_limit_addr2name_family ,
|
||||
.Nm cap_net_limit_bind ,
|
||||
.Nm cap_net_limit_connect ,
|
||||
.Nm cap_net_limit_init ,
|
||||
.Nm cap_net_limit_name2addr ,
|
||||
.Nm cap_net_limit_name2addr_family ,
|
||||
.Nd "library for networking in capability mode"
|
||||
.Sh LIBRARY
|
||||
.Lb libcap_net
|
||||
.Sh SYNOPSIS
|
||||
.In sys/nv.h
|
||||
.In libcasper.h
|
||||
.In casper/cap_net.h
|
||||
.Ft int
|
||||
.Fn cap_bind "cap_channel_t *chan" "int s" "const struct sockaddr *addr" "socklen_t addrlen"
|
||||
.Ft int
|
||||
.Fn cap_connect "cap_channel_t *chan" "int s" "const struct sockaddr *name" "socklen_t namelen"
|
||||
.Ft int
|
||||
.Fn cap_getaddrinfo "cap_channel_t *chan" "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct addrinfo **res"
|
||||
.Ft int
|
||||
.Fn cap_getnameinfo "cap_channel_t *chan" "const struct sockaddr *sa" "socklen_t salen" "char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
|
||||
.Ft "struct hostent *"
|
||||
.Fn cap_gethostbyname "const cap_channel_t *chan" "const char *name"
|
||||
.Ft "struct hostent *"
|
||||
.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af"
|
||||
.Ft "struct hostent *"
|
||||
.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_init "cap_channel_t *chan" "uint64_t mode"
|
||||
.Ft int
|
||||
.Fn cap_net_limit "cap_net_limit_t *limit"
|
||||
.Ft void
|
||||
.Fn cap_net_free "cap_net_limit_t *limit"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_addr2name_family "cap_net_limit_t *limit" "int *family" "size_t size"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_addr2name "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_name2addr_family "cap_net_limit_t *limit" "int *family" "size_t size"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_name2addr "cap_net_limit_t *limit" "const char *name" "const char *serv"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_connect "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
|
||||
.Ft "cap_net_limit_t *"
|
||||
.Fn cap_net_limit_bind "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
|
||||
.Sh DESCRIPTION
|
||||
.Pp
|
||||
The functions
|
||||
.Fn cap_bind,
|
||||
.Fn cap_connect,
|
||||
.Fn cap_gethostbyname ,
|
||||
.Fn cap_gethostbyname2 ,
|
||||
.Fn cap_gethostbyaddr
|
||||
and
|
||||
.Fn cap_getnameinfo
|
||||
are respectively equivalent to
|
||||
.Xr bind 2 ,
|
||||
.Xr connect 2 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr gethostbyname2 3 ,
|
||||
.Xr gethostbyaddr 3
|
||||
and
|
||||
.Xr getnameinfo 3
|
||||
except that the connection to the
|
||||
.Nm system.net
|
||||
service needs to be provided.
|
||||
.Sh LIMITS
|
||||
By default, the cap_net capability provides unrestricted access to the network
|
||||
namespace.
|
||||
Applications typically only require access to a small portion of the network
|
||||
namespace:
|
||||
.Fn cap_net_limit
|
||||
interface can be used to restrict access to the network.
|
||||
.Fn cap_net_limit_init
|
||||
returns an opaque limit handle used to store a list of capabilities.
|
||||
The
|
||||
.Fv mode
|
||||
restricts the functionality of the service.
|
||||
Modes are encoded using the following flags:
|
||||
.Pp
|
||||
.Bd -literal -offset indent -compact
|
||||
CAPNET_ADDR2NAME reverse DNS lookups are allowed with
|
||||
cap_getnameinfo
|
||||
CAPNET_NAME2ADDR name resolution is allowed with
|
||||
cap_getaddrinfo
|
||||
CAPNET_DEPRECATED_ADDR2NAME reverse DNS lookups are allowed with
|
||||
cap_gethostbyaddr
|
||||
CAPNET_DEPRECATED_NAME2ADDR name resolution is allowed with
|
||||
cap_gethostbyname and cap_gethostbyname2
|
||||
CAPNET_BIND bind syscall is allowed
|
||||
CAPNET_CONNECT connect syscall is allowed
|
||||
CAPNET_CONNECTDNS connect syscall is allowed to the values
|
||||
returned from privies call to
|
||||
the cap_getaddrinfo or cap_gethostbyname
|
||||
.Ed
|
||||
.Pp
|
||||
.Fn cap_net_limit_addr2name_family
|
||||
limits the
|
||||
.Fn cap_getnameinfo
|
||||
and
|
||||
.Fn cap_gethostbyaddr
|
||||
to do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.)
|
||||
.Pp
|
||||
.Fn cap_net_limit_addr2name
|
||||
limits the
|
||||
.Fn cap_getnameinfo
|
||||
and
|
||||
.Fn cap_gethostbyaddr
|
||||
to do reverse DNS lookups only on those specific structures.
|
||||
.Pp
|
||||
.Fn cap_net_limit_name2addr_family
|
||||
limits the
|
||||
.Fn cap_getaddrinfo ,
|
||||
.Fn cap_gethostbyname
|
||||
and
|
||||
.Fn cap_gethostbyname2
|
||||
to do the name resolution on specific family (AF_INET, AF_INET6, etc.)
|
||||
.Pp
|
||||
.Fn cap_net_limit_addr2name
|
||||
restricts
|
||||
.Fn cap_getaddrinfo ,
|
||||
.Fn cap_gethostbyname
|
||||
and
|
||||
.Fn cap_gethostbyname2
|
||||
to a set of domains.
|
||||
.Pp
|
||||
.Fn cap_net_limit_bind
|
||||
limits
|
||||
.Fn cap_bind
|
||||
to bind only on those specific structures.
|
||||
.Pp
|
||||
.Fn cap_net_limit_connect
|
||||
limits
|
||||
.Fn cap_connect
|
||||
to connect only on those specific structures.
|
||||
If the CAPNET_CONNECTDNS is set the limits are extended to the values returned
|
||||
by
|
||||
.Fn cap_getaddrinfo ,
|
||||
.Fn cap_gethostbyname
|
||||
and
|
||||
.Fn cap_gethostbyname2
|
||||
In case of the
|
||||
.Fn cap_getaddrinfo
|
||||
the restriction is strict.
|
||||
In case of the
|
||||
.Fn cap_gethostbyname
|
||||
and
|
||||
.Fn cap_gethostbyname2
|
||||
any port will be accepted in the
|
||||
.Fn cap_connect
|
||||
function.
|
||||
.Pp
|
||||
.Fn cap_net_limit
|
||||
applies a set of sysctl limits to the capability, denying access to sysctl
|
||||
variables not belonging to the set.
|
||||
.Pp
|
||||
Once a set of limits is applied, subsequent calls to
|
||||
.Fn cap_net_limit
|
||||
will fail unless the new set is a subset of the current set.
|
||||
.Pp
|
||||
The
|
||||
.Fn cap_net_limit
|
||||
will consume the limits.
|
||||
If the
|
||||
.Fn cap_net_limit
|
||||
was not called the rights may be freed using
|
||||
.Fn cap_net_free .
|
||||
Multiple calls to
|
||||
.Fn cap_net_limit_addr2name_family ,
|
||||
.Fn cap_net_limit_addr2name ,
|
||||
.Fn cap_net_limit_name2addr_family ,
|
||||
.Fn cap_net_limit_name2addr ,
|
||||
.Fn cap_net_limit_connect ,
|
||||
and
|
||||
.Fn cap_net_limit_bind
|
||||
is supported, each call is extending preview capabilities.
|
||||
.Sh EXAMPLES
|
||||
The following example first opens a capability to casper and then uses this
|
||||
capability to create the
|
||||
.Nm system.net
|
||||
casper service and uses it to resolve a host and connect to it.
|
||||
.Bd -literal
|
||||
cap_channel_t *capcas, *capnet;
|
||||
cap_net_limit_t *limit;
|
||||
int familylimit, error, s;
|
||||
const char *host = "example.com";
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
/* Open capability to Casper. */
|
||||
capcas = cap_init();
|
||||
if (capcas == NULL)
|
||||
err(1, "Unable to contact Casper");
|
||||
|
||||
/* Cache NLA for gai_strerror. */
|
||||
caph_cache_catpages();
|
||||
|
||||
/* Enter capability mode sandbox. */
|
||||
if (caph_enter_casper() < 0)
|
||||
err(1, "Unable to enter capability mode");
|
||||
|
||||
/* Use Casper capability to create capability to the system.net service. */
|
||||
capnet = cap_service_open(capcas, "system.net");
|
||||
if (capnet == NULL)
|
||||
err(1, "Unable to open system.net service");
|
||||
|
||||
/* Close Casper capability. */
|
||||
cap_close(capcas);
|
||||
|
||||
/* Limit system.net to reserve IPv4 addresses, to host example.com . */
|
||||
limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS);
|
||||
if (limit == NULL)
|
||||
err(1, "Unable to create limits.");
|
||||
cap_net_limit_name2addr(limit, host, "80");
|
||||
familylimit = AF_INET;
|
||||
cap_net_limit_name2addr_family(limit, &familylimit, 1);
|
||||
if (cap_net_limit(limit) < 0)
|
||||
err(1, "Unable to apply limits.");
|
||||
|
||||
/* Find IP addresses for the given host. */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
error = cap_getaddrinfo(capnet, host, "80", &hints, &res);
|
||||
if (error != 0)
|
||||
errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error));
|
||||
|
||||
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (s < 0)
|
||||
err(1, "Unable to create socket");
|
||||
|
||||
if (cap_connect(capnet, s, res->ai_addr, res->ai_addrlen) < 0)
|
||||
err(1, "Unable to connect to host");
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr bind 2 ,
|
||||
.Xr cap_enter 2 ,
|
||||
.Xr connect 2 ,
|
||||
.Xr caph_enter 3 ,
|
||||
.Xr err 3 ,
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr gethostbyname2 3 ,
|
||||
.Xr getnameinfo 3 ,
|
||||
.Xr capsicum 4 ,
|
||||
.Xr nv 9
|
||||
.Sh AUTHORS
|
||||
.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org
|
1385
lib/libcasper/services/cap_net/cap_net.c
Normal file
1385
lib/libcasper/services/cap_net/cap_net.c
Normal file
File diff suppressed because it is too large
Load Diff
165
lib/libcasper/services/cap_net/cap_net.h
Normal file
165
lib/libcasper/services/cap_net/cap_net.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _CAP_NETWORK_H_
|
||||
#define _CAP_NETWORK_H_
|
||||
|
||||
#ifdef HAVE_CASPER
|
||||
#define WITH_CASPER
|
||||
#endif
|
||||
|
||||
#include <sys/dnv.h>
|
||||
#include <sys/nv.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
|
||||
struct cap_net_limit;
|
||||
typedef struct cap_net_limit cap_net_limit_t;
|
||||
|
||||
#define CAPNET_ADDR2NAME (0x01)
|
||||
#define CAPNET_NAME2ADDR (0x02)
|
||||
#define CAPNET_DEPRECATED_ADDR2NAME (0x04)
|
||||
#define CAPNET_DEPRECATED_NAME2ADDR (0x08)
|
||||
#define CAPNET_CONNECT (0x10)
|
||||
#define CAPNET_BIND (0x20)
|
||||
#define CAPNET_CONNECTDNS (0x40)
|
||||
|
||||
#ifdef WITH_CASPER
|
||||
/* Capability functions. */
|
||||
int cap_bind(cap_channel_t *chan, int s, const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
int cap_connect(cap_channel_t *chan, int s, const struct sockaddr *name,
|
||||
socklen_t namelen);
|
||||
|
||||
int cap_getaddrinfo(cap_channel_t *chan, const char *hostname,
|
||||
const char *servname, const struct addrinfo *hints, struct addrinfo **res);
|
||||
int cap_getnameinfo(cap_channel_t *chan, const struct sockaddr *sa,
|
||||
socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen,
|
||||
int flags);
|
||||
|
||||
/* Limit functions. */
|
||||
cap_net_limit_t *cap_net_limit_init(cap_channel_t *chan, uint64_t mode);
|
||||
int cap_net_limit(cap_net_limit_t *limit);
|
||||
void cap_net_free(cap_net_limit_t *limit);
|
||||
|
||||
cap_net_limit_t *cap_net_limit_addr2name_family(cap_net_limit_t *limit,
|
||||
int *family, size_t size);
|
||||
cap_net_limit_t *cap_net_limit_addr2name(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa, socklen_t salen);
|
||||
|
||||
cap_net_limit_t *cap_net_limit_name2addr_family(cap_net_limit_t *limit,
|
||||
int *family, size_t size);
|
||||
cap_net_limit_t *cap_net_limit_name2addr(cap_net_limit_t *limit,
|
||||
const char *name, const char *serv);
|
||||
|
||||
cap_net_limit_t *cap_net_limit_connect(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa, socklen_t salen);
|
||||
|
||||
cap_net_limit_t *cap_net_limit_bind(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa, socklen_t salen);
|
||||
|
||||
/* Deprecated functions. */
|
||||
struct hostent *cap_gethostbyname(cap_channel_t *chan, const char *name);
|
||||
struct hostent *cap_gethostbyname2(cap_channel_t *chan, const char *name,
|
||||
int af);
|
||||
struct hostent *cap_gethostbyaddr(cap_channel_t *chan, const void *addr,
|
||||
socklen_t len, int af);
|
||||
#else
|
||||
/* Capability functions. */
|
||||
#define cap_bind(chan, s, addr, addrlen) \
|
||||
bind(s, addr, addrlen)
|
||||
#define cap_connect(chan, s, name, namelen) \
|
||||
connect(s, name, namelen)
|
||||
#define cap_getaddrinfo(chan, hostname, servname, hints, res) \
|
||||
getaddrinfo(hostname, servname, hints, res)
|
||||
#define cap_getnameinfo(chan, sa, salen, host, hostlen, serv, servlen, flags) \
|
||||
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
|
||||
/* Limit functions. */
|
||||
#define cap_net_limit_init(chan, mode) ((cap_net_limit_t *)malloc(8))
|
||||
#define cap_net_free(limit) free(limit)
|
||||
static inline int
|
||||
cap_net_limit(cap_net_limit_t *limit)
|
||||
{
|
||||
free(limit);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_addr2name_family(cap_net_limit_t *limit,
|
||||
int *family __unused, size_t size __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_addr2name(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa __unused, socklen_t salen __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_name2addr_family(cap_net_limit_t *limit,
|
||||
int *family __unused, size_t size __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_name2addr(cap_net_limit_t *limit,
|
||||
const char *name __unused, const char *serv __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_connect(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa __unused, socklen_t salen __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
static inline cap_net_limit_t *
|
||||
cap_net_limit_bind(cap_net_limit_t *limit,
|
||||
const struct sockaddr *sa __unused, socklen_t salen __unused)
|
||||
{
|
||||
return (limit);
|
||||
}
|
||||
|
||||
/* Deprecated functions. */
|
||||
#define cap_gethostbyname(chan, name) gethostbyname(name)
|
||||
#define cap_gethostbyname2(chan, name, type) gethostbyname2(name, type)
|
||||
#define cap_gethostbyaddr(chan, addr, len, type) gethostbyaddr(addr, len, type)
|
||||
#endif
|
||||
|
||||
#endif /* !_CAP_NETWORK_H_ */
|
16
lib/libcasper/services/cap_net/tests/Makefile
Normal file
16
lib/libcasper/services/cap_net/tests/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
ATF_TESTS_C= net_test
|
||||
|
||||
.if ${MK_CASPER} != "no"
|
||||
LIBADD+= casper
|
||||
LIBADD+= cap_net
|
||||
CFLAGS+=-DWITH_CASPER
|
||||
.endif
|
||||
LIBADD+= nv
|
||||
|
||||
WARNS?= 3
|
||||
|
||||
.include <bsd.test.mk>
|
1160
lib/libcasper/services/cap_net/tests/net_test.c
Normal file
1160
lib/libcasper/services/cap_net/tests/net_test.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -89,6 +89,7 @@ _LIBRARIES= \
|
||||
cap_dns \
|
||||
cap_fileargs \
|
||||
cap_grp \
|
||||
cap_net \
|
||||
cap_pwd \
|
||||
cap_sysctl \
|
||||
cap_syslog \
|
||||
@ -637,6 +638,7 @@ LIBBSNMPDIR= ${OBJTOP}/lib/libbsnmp/libbsnmp
|
||||
LIBCASPERDIR= ${OBJTOP}/lib/libcasper/libcasper
|
||||
LIBCAP_DNSDIR= ${OBJTOP}/lib/libcasper/services/cap_dns
|
||||
LIBCAP_GRPDIR= ${OBJTOP}/lib/libcasper/services/cap_grp
|
||||
LIBCAP_NETDIR= ${OBJTOP}/lib/libcasper/services/cap_net
|
||||
LIBCAP_PWDDIR= ${OBJTOP}/lib/libcasper/services/cap_pwd
|
||||
LIBCAP_SYSCTLDIR= ${OBJTOP}/lib/libcasper/services/cap_sysctl
|
||||
LIBCAP_SYSLOGDIR= ${OBJTOP}/lib/libcasper/services/cap_syslog
|
||||
|
@ -260,7 +260,7 @@ igrab(struct inode *inode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = vget(inode, 0, curthread);
|
||||
error = vget(inode, 0);
|
||||
if (error)
|
||||
return (NULL);
|
||||
|
||||
|
@ -656,7 +656,7 @@ autofs_node_vn(struct autofs_node *anp, struct mount *mp, int flags,
|
||||
|
||||
vp = anp->an_vnode;
|
||||
if (vp != NULL) {
|
||||
error = vget(vp, flags | LK_RETRY, curthread);
|
||||
error = vget(vp, flags | LK_RETRY);
|
||||
if (error != 0) {
|
||||
AUTOFS_WARN("vget failed with error %d", error);
|
||||
sx_xunlock(&anp->an_vnode_lock);
|
||||
|
@ -799,7 +799,7 @@ ext2_reload(struct mount *mp, struct thread *td)
|
||||
/*
|
||||
* Step 4: invalidate all cached file data.
|
||||
*/
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto loop;
|
||||
}
|
||||
@ -1158,7 +1158,7 @@ ext2_sync(struct mount *mp, int waitfor)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td);
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
|
||||
if (error) {
|
||||
if (error == ENOENT) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
|
@ -163,7 +163,7 @@ fdesc_root(struct mount *mp, int flags, struct vnode **vpp)
|
||||
* Return locked reference to root.
|
||||
*/
|
||||
vp = VFSTOFDESC(mp)->f_root;
|
||||
vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
|
||||
vget(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp,
|
||||
vp = fd->fd_vnode;
|
||||
VI_LOCK(vp);
|
||||
mtx_unlock(&fdesc_hashmtx);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td))
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
|
||||
goto loop;
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
@ -232,7 +232,7 @@ fdesc_allocvp(fdntype ftype, unsigned fd_fd, int ix, struct mount *mp,
|
||||
vp2 = fd2->fd_vnode;
|
||||
VI_LOCK(vp2);
|
||||
mtx_unlock(&fdesc_hashmtx);
|
||||
error = vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK, td);
|
||||
error = vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK);
|
||||
/* Someone beat us, dec use count and wait for reclaim */
|
||||
vgone(vp);
|
||||
vput(vp);
|
||||
|
@ -610,7 +610,7 @@ fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp)
|
||||
int err = 0;
|
||||
|
||||
if (data->vroot != NULL) {
|
||||
err = vget(data->vroot, lkflags, curthread);
|
||||
err = vget(data->vroot, lkflags);
|
||||
if (err == 0)
|
||||
*vpp = data->vroot;
|
||||
} else {
|
||||
|
@ -921,7 +921,7 @@ msdosfs_sync(struct mount *mp, int waitfor)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td);
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
|
||||
if (error) {
|
||||
if (error == ENOENT) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, nvp);
|
||||
|
@ -1828,7 +1828,7 @@ nfs_sync(struct mount *mp, int waitfor)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto loop;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ nullfs_root(mp, flags, vpp)
|
||||
NULLFSDEBUG("nullfs_root(mp = %p, vp = %p)\n", mp,
|
||||
mntdata->nullm_lowerrootvp);
|
||||
|
||||
error = vget(mntdata->nullm_lowerrootvp, flags, curthread);
|
||||
error = vget(mntdata->nullm_lowerrootvp, flags);
|
||||
if (error == 0) {
|
||||
error = null_nodeget(mp, mntdata->nullm_lowerrootvp, &vp);
|
||||
if (error == 0) {
|
||||
|
@ -136,7 +136,7 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp,
|
||||
vp = pvd->pvd_vnode;
|
||||
VI_LOCK(vp);
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread) == 0) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) == 0) {
|
||||
++pfs_vncache_hits;
|
||||
*vpp = vp;
|
||||
/*
|
||||
@ -218,7 +218,7 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp,
|
||||
vp = pvd2->pvd_vnode;
|
||||
VI_LOCK(vp);
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread) == 0) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) == 0) {
|
||||
++pfs_vncache_hits;
|
||||
vgone(*vpp);
|
||||
vput(*vpp);
|
||||
|
@ -124,7 +124,7 @@ smbfs_node_alloc(struct mount *mp, struct vnode *dvp, const char *dirnm,
|
||||
if (dvp == NULL)
|
||||
return EINVAL;
|
||||
vp = VTOSMB(VTOSMB(dvp)->n_parent)->n_vnode;
|
||||
error = vget(vp, LK_EXCLUSIVE, td);
|
||||
error = vget(vp, LK_EXCLUSIVE);
|
||||
if (error == 0)
|
||||
*vpp = vp;
|
||||
return error;
|
||||
|
@ -329,7 +329,7 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp)
|
||||
|
||||
if (smp->sm_root) {
|
||||
*vpp = SMBTOV(smp->sm_root);
|
||||
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY);
|
||||
}
|
||||
scred = smbfs_malloc_scred();
|
||||
smb_makescred(scred, td, cred);
|
||||
|
@ -588,6 +588,7 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
enum vgetstate vs;
|
||||
struct tmpfs_mount *tm;
|
||||
vm_object_t object;
|
||||
int error;
|
||||
@ -600,18 +601,15 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
|
||||
TMPFS_NODE_ASSERT_LOCKED(node);
|
||||
if ((vp = node->tn_vnode) != NULL) {
|
||||
MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0);
|
||||
VI_LOCK(vp);
|
||||
if ((node->tn_type == VDIR && node->tn_dir.tn_parent == NULL) ||
|
||||
(VN_IS_DOOMED(vp) &&
|
||||
(lkflag & LK_NOWAIT) != 0)) {
|
||||
VI_UNLOCK(vp);
|
||||
TMPFS_NODE_UNLOCK(node);
|
||||
error = ENOENT;
|
||||
vp = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (VN_IS_DOOMED(vp)) {
|
||||
VI_UNLOCK(vp);
|
||||
node->tn_vpstate |= TMPFS_VNODE_WRECLAIM;
|
||||
while ((node->tn_vpstate & TMPFS_VNODE_WRECLAIM) != 0) {
|
||||
msleep(&node->tn_vnode, TMPFS_NODE_MTX(node),
|
||||
@ -619,8 +617,9 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
vs = vget_prep(vp);
|
||||
TMPFS_NODE_UNLOCK(node);
|
||||
error = vget(vp, lkflag | LK_INTERLOCK, curthread);
|
||||
error = vget_finish(vp, lkflag, vs);
|
||||
if (error == ENOENT) {
|
||||
TMPFS_NODE_LOCK(node);
|
||||
goto loop;
|
||||
|
@ -130,8 +130,7 @@ tmpfs_update_mtime(struct mount *mp, bool lazy)
|
||||
* metadata changes now.
|
||||
*/
|
||||
if (!lazy || obj->generation != obj->cleangeneration) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK,
|
||||
curthread) != 0)
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK) != 0)
|
||||
continue;
|
||||
tmpfs_check_mtime(vp);
|
||||
if (!lazy)
|
||||
|
@ -754,7 +754,7 @@ mqfs_allocv(struct mount *mp, struct vnode **vpp, struct mqfs_node *pn)
|
||||
found:
|
||||
*vpp = vd->mv_vnode;
|
||||
sx_xunlock(&mqfs->mi_lock);
|
||||
error = vget(*vpp, LK_RETRY | LK_EXCLUSIVE, curthread);
|
||||
error = vget(*vpp, LK_RETRY | LK_EXCLUSIVE);
|
||||
vdrop(*vpp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -2427,11 +2427,11 @@ sys___getcwd(struct thread *td, struct __getcwd_args *uap)
|
||||
if (buflen > MAXPATHLEN)
|
||||
buflen = MAXPATHLEN;
|
||||
|
||||
buf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
buf = uma_zalloc(namei_zone, M_WAITOK);
|
||||
error = vn_getcwd(td, buf, &retbuf, &buflen);
|
||||
if (error == 0)
|
||||
error = copyout(retbuf, uap->buf, buflen);
|
||||
free(buf, M_TEMP);
|
||||
uma_zfree(namei_zone, buf);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2983,8 +2983,6 @@ DB_SHOW_COMMAND(vpath, db_show_vpath)
|
||||
|
||||
#endif
|
||||
|
||||
extern uma_zone_t namei_zone;
|
||||
|
||||
static bool __read_frequently cache_fast_lookup = true;
|
||||
SYSCTL_BOOL(_vfs, OID_AUTO, cache_fast_lookup, CTLFLAG_RW,
|
||||
&cache_fast_lookup, 0, "");
|
||||
|
@ -1348,7 +1348,7 @@ vfs_stdsync(mp, waitfor)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if ((error = vget(vp, lockreq, td)) != 0) {
|
||||
if ((error = vget(vp, lockreq)) != 0) {
|
||||
if (error == ENOENT) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto loop;
|
||||
|
@ -504,8 +504,7 @@ namei(struct nameidata *ndp)
|
||||
* Get a buffer for the name to be translated, and copy the
|
||||
* name into the buffer.
|
||||
*/
|
||||
if ((cnp->cn_flags & HASBUF) == 0)
|
||||
cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
|
||||
cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
|
||||
if (ndp->ni_segflg == UIO_SYSSPACE)
|
||||
error = copystr(ndp->ni_dirp, cnp->cn_pnbuf, MAXPATHLEN,
|
||||
&ndp->ni_pathlen);
|
||||
|
@ -2856,12 +2856,10 @@ vget_abort(struct vnode *vp, enum vgetstate vs)
|
||||
}
|
||||
|
||||
int
|
||||
vget(struct vnode *vp, int flags, struct thread *td)
|
||||
vget(struct vnode *vp, int flags)
|
||||
{
|
||||
enum vgetstate vs;
|
||||
|
||||
MPASS(td == curthread);
|
||||
|
||||
vs = vget_prep(vp);
|
||||
return (vget_finish(vp, flags, vs));
|
||||
}
|
||||
@ -4684,7 +4682,7 @@ vfs_periodic_msync_inactive(struct mount *mp, int flags)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if (vget(vp, lkflags, td) == 0) {
|
||||
if (vget(vp, lkflags) == 0) {
|
||||
obj = vp->v_object;
|
||||
if (obj != NULL && (vp->v_vflag & VV_NOSYNC) == 0) {
|
||||
VM_OBJECT_WLOCK(obj);
|
||||
|
@ -3,6 +3,6 @@
|
||||
.PATH: ${SRCTOP}/sys/dev/nvd
|
||||
|
||||
KMOD= nvd
|
||||
SRCS= nvd.c opt_geom.h device_if.h bus_if.h
|
||||
SRCS= nvd.c opt_geom.h device_if.h bus_if.h pci_if.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -31,7 +31,7 @@ S= ${SRCTOP}/sys
|
||||
|
||||
KMOD= cp2112
|
||||
SRCS= cp2112.c
|
||||
SRCS+= opt_bus.h opt_usb.h
|
||||
SRCS+= opt_bus.h opt_platform.h opt_usb.h
|
||||
SRCS+= device_if.h bus_if.h gpio_if.h iicbus_if.h usb_if.h usbdevs.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -829,7 +829,6 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
|
||||
#ifdef SCTP_ASOCLOG_OF_TSNS
|
||||
sctp_print_out_track_log(stcb);
|
||||
#endif
|
||||
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
|
||||
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
|
||||
SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: finished\n");
|
||||
@ -1866,7 +1865,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
/* send up all the data */
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
|
||||
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
|
||||
sctp_report_all_outbound(stcb, 0, SCTP_SO_LOCKED);
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
stcb->asoc.strmout[i].chunks_on_queues = 0;
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
|
@ -13148,12 +13148,21 @@ sctp_lower_sosend(struct socket *so,
|
||||
if (sinfo_flags & SCTP_UNORDERED) {
|
||||
SCTP_STAT_INCR(sctps_sends_with_unord);
|
||||
}
|
||||
sp->processing = 1;
|
||||
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
|
||||
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
} else {
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
|
||||
if (sp->processing) {
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
} else {
|
||||
sp->processing = 1;
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
if (sp == NULL) {
|
||||
/* ???? Huh ??? last msg is gone */
|
||||
@ -13195,13 +13204,14 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
/* Update the mbuf and count */
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
|
||||
if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
|
||||
(stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
|
||||
/*
|
||||
* we need to get out. Peer probably
|
||||
* aborted.
|
||||
*/
|
||||
sctp_m_freem(mm);
|
||||
if (stcb->asoc.state & SCTP_PCB_FLAGS_WAS_ABORTED) {
|
||||
if (stcb->asoc.state & SCTP_STATE_WAS_ABORTED) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
|
||||
error = ECONNRESET;
|
||||
}
|
||||
@ -13405,7 +13415,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
|
||||
if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||
|
||||
(stcb->asoc.state & SCTP_STATE_WAS_ABORTED)) {
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
goto out_unlocked;
|
||||
}
|
||||
@ -13421,6 +13432,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
strm->last_msg_incomplete = 0;
|
||||
asoc->stream_locked = 0;
|
||||
}
|
||||
sp->processing = 0;
|
||||
} else {
|
||||
SCTP_PRINTF("Huh no sp TSNH?\n");
|
||||
strm->last_msg_incomplete = 0;
|
||||
|
@ -4733,6 +4733,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* there is no asoc, really TSNH :-0 */
|
||||
return (1);
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
sctp_free_remote_addr(stcb->asoc.alternate);
|
||||
stcb->asoc.alternate = NULL;
|
||||
@ -4767,6 +4768,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* nope, reader or writer in the way */
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
|
||||
/* no asoc destroyed */
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
sctp_log_closing(inp, stcb, 8);
|
||||
@ -4835,6 +4837,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
|
||||
@ -4868,10 +4871,12 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
if (from_inpcbfree == SCTP_NORMAL_PROC) {
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
}
|
||||
/* Double check the GONE flag */
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
@ -4919,6 +4924,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
return (0);
|
||||
}
|
||||
@ -4950,7 +4956,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
* in case.
|
||||
*/
|
||||
/* anything on the wheel needs to be removed */
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
struct sctp_stream_out *outs;
|
||||
|
||||
@ -4981,7 +4986,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
|
||||
}
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
|
||||
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
|
||||
@ -5183,6 +5187,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* Insert new items here :> */
|
||||
|
||||
/* Get rid of LOCK */
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
|
@ -534,6 +534,7 @@ struct sctp_stream_queue_pending {
|
||||
uint8_t sender_all_done;
|
||||
uint8_t put_last_out;
|
||||
uint8_t discard_rest;
|
||||
uint8_t processing;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -4239,7 +4239,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
}
|
||||
|
||||
void
|
||||
sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked)
|
||||
sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_stream_out *outs;
|
||||
@ -4261,9 +4261,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
|
||||
return;
|
||||
}
|
||||
/* now through all the gunk freeing chunks */
|
||||
if (holds_lock == 0) {
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
}
|
||||
/* sent queue SHOULD be empty */
|
||||
TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
|
||||
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
|
||||
@ -4340,10 +4337,6 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock,
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
}
|
||||
|
||||
if (holds_lock == 0) {
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -4363,8 +4356,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
|
||||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
|
||||
return;
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
|
||||
/* Tell them we lost the asoc */
|
||||
sctp_report_all_outbound(stcb, error, 0, so_locked);
|
||||
sctp_report_all_outbound(stcb, error, so_locked);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
if (from_peer) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
|
||||
} else {
|
||||
@ -4393,7 +4389,6 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
if (stcb != NULL) {
|
||||
/* We have a TCB to abort, send notification too */
|
||||
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
|
||||
/* Ok, now lets free it */
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
|
||||
@ -4482,8 +4477,6 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
|
||||
}
|
||||
/* notify the peer */
|
||||
sctp_send_abort_tcb(stcb, op_err, so_locked);
|
||||
|
@ -164,7 +164,7 @@ void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
|
||||
/* Stop all timers for association and remote addresses. */
|
||||
void sctp_stop_association_timers(struct sctp_tcb *, bool);
|
||||
|
||||
void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int);
|
||||
void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int);
|
||||
|
||||
int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
|
||||
|
||||
|
@ -149,21 +149,21 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status,
|
||||
* buffer and for vrele'ing ni_startdir.
|
||||
*/
|
||||
#define RDONLY 0x00000200 /* lookup with read-only semantics */
|
||||
#define HASBUF 0x00000400 /* has allocated pathname buffer */
|
||||
#define SAVENAME 0x00000800 /* save pathname buffer */
|
||||
#define SAVESTART 0x00001000 /* save starting directory */
|
||||
#define ISWHITEOUT 0x00002000 /* found whiteout */
|
||||
#define DOWHITEOUT 0x00004000 /* do whiteouts */
|
||||
#define WILLBEDIR 0x00008000 /* new files will be dirs; allow trailing / */
|
||||
#define ISOPEN 0x00010000 /* caller is opening; return a real vnode. */
|
||||
#define NOCROSSMOUNT 0x00020000 /* do not cross mount points */
|
||||
#define NOMACCHECK 0x00040000 /* do not perform MAC checks */
|
||||
#define AUDITVNODE1 0x00080000 /* audit the looked up vnode information */
|
||||
#define AUDITVNODE2 0x00100000 /* audit the looked up vnode information */
|
||||
#define NOCAPCHECK 0x00200000 /* do not perform capability checks */
|
||||
#define SAVENAME 0x00000400 /* save pathname buffer */
|
||||
#define SAVESTART 0x00000800 /* save starting directory */
|
||||
#define ISWHITEOUT 0x00001000 /* found whiteout */
|
||||
#define DOWHITEOUT 0x00002000 /* do whiteouts */
|
||||
#define WILLBEDIR 0x00004000 /* new files will be dirs; allow trailing / */
|
||||
#define ISOPEN 0x00008000 /* caller is opening; return a real vnode. */
|
||||
#define NOCROSSMOUNT 0x00010000 /* do not cross mount points */
|
||||
#define NOMACCHECK 0x00020000 /* do not perform MAC checks */
|
||||
#define AUDITVNODE1 0x00040000 /* audit the looked up vnode information */
|
||||
#define AUDITVNODE2 0x00080000 /* audit the looked up vnode information */
|
||||
#define NOCAPCHECK 0x00100000 /* do not perform capability checks */
|
||||
/* UNUSED 0x00400000 */
|
||||
/* UNUSED 0x00200000 */
|
||||
/* UNUSED 0x00800000 */
|
||||
/* UNUSED 0x01000000 */
|
||||
#define HASBUF 0x01000000 /* has allocated pathname buffer */
|
||||
#define NOEXECCHECK 0x02000000 /* do not perform exec check on dir */
|
||||
#define MAKEENTRY 0x04000000 /* entry is to be added to name cache */
|
||||
#define ISSYMLINK 0x08000000 /* symlink needs interpretation */
|
||||
@ -176,7 +176,8 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status,
|
||||
* Flags which must not be passed in by callers.
|
||||
*/
|
||||
#define NAMEI_INTERNAL_FLAGS \
|
||||
(NOEXECCHECK | MAKEENTRY | ISSYMLINK | ISLASTCN | ISDOTDOT | TRAILINGSLASH)
|
||||
(HASBUF | NOEXECCHECK | MAKEENTRY | ISSYMLINK | ISLASTCN | ISDOTDOT | \
|
||||
TRAILINGSLASH)
|
||||
|
||||
/*
|
||||
* Namei results flags
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1300108 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1300109 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
@ -680,7 +680,7 @@ void vlazy(struct vnode *);
|
||||
void vdrop(struct vnode *);
|
||||
void vdropl(struct vnode *);
|
||||
int vflush(struct mount *mp, int rootrefs, int flags, struct thread *td);
|
||||
int vget(struct vnode *vp, int flags, struct thread *td);
|
||||
int vget(struct vnode *vp, int flags);
|
||||
enum vgetstate vget_prep_smr(struct vnode *vp);
|
||||
enum vgetstate vget_prep(struct vnode *vp);
|
||||
int vget_finish(struct vnode *vp, int flags, enum vgetstate vs);
|
||||
|
@ -3463,7 +3463,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
|
||||
*/
|
||||
pwd = pwd_hold(td);
|
||||
dvp = pwd->pwd_cdir;
|
||||
if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
|
||||
if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
|
||||
vput(fdvp);
|
||||
pwd_drop(pwd);
|
||||
break;
|
||||
|
@ -13624,8 +13624,7 @@ softdep_request_cleanup_flush(mp, ump)
|
||||
VI_UNLOCK(lvp);
|
||||
continue;
|
||||
}
|
||||
if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT,
|
||||
td) != 0) {
|
||||
if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT) != 0) {
|
||||
failed_vnode = 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -974,7 +974,7 @@ ffs_reload(struct mount *mp, struct thread *td, int flags)
|
||||
/*
|
||||
* Step 4: invalidate all cached file data.
|
||||
*/
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto loop;
|
||||
}
|
||||
@ -1758,8 +1758,7 @@ ffs_sync_lazy(mp)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if ((error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK,
|
||||
td)) != 0)
|
||||
if ((error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK)) != 0)
|
||||
continue;
|
||||
#ifdef QUOTA
|
||||
qsyncvp(vp);
|
||||
@ -1856,7 +1855,7 @@ ffs_sync(mp, waitfor)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if ((error = vget(vp, lockreq, td)) != 0) {
|
||||
if ((error = vget(vp, lockreq)) != 0) {
|
||||
if (error == ENOENT || error == ENOLCK) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto loop;
|
||||
|
@ -613,7 +613,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
|
||||
*/
|
||||
again:
|
||||
MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto again;
|
||||
}
|
||||
@ -680,7 +680,7 @@ quotaoff1(struct thread *td, struct mount *mp, int type)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
goto again;
|
||||
}
|
||||
@ -1064,7 +1064,6 @@ int
|
||||
qsync(struct mount *mp)
|
||||
{
|
||||
struct ufsmount *ump = VFSTOUFS(mp);
|
||||
struct thread *td = curthread; /* XXX */
|
||||
struct vnode *vp, *mvp;
|
||||
struct dquot *dq;
|
||||
int i, error;
|
||||
@ -1088,7 +1087,7 @@ qsync(struct mount *mp)
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
}
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
|
||||
error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK);
|
||||
if (error) {
|
||||
if (error == ENOENT) {
|
||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
|
||||
|
@ -673,7 +673,7 @@ vm_fault_lock_vnode(struct faultstate *fs, bool objlocked)
|
||||
* paging-in-progress count incremented. Otherwise, we could
|
||||
* deadlock.
|
||||
*/
|
||||
error = vget(vp, locked | LK_CANRECURSE | LK_NOWAIT, curthread);
|
||||
error = vget(vp, locked | LK_CANRECURSE | LK_NOWAIT);
|
||||
if (error == 0) {
|
||||
fs->vp = vp;
|
||||
return (KERN_SUCCESS);
|
||||
@ -684,7 +684,7 @@ vm_fault_lock_vnode(struct faultstate *fs, bool objlocked)
|
||||
unlock_and_deallocate(fs);
|
||||
else
|
||||
fault_deallocate(fs);
|
||||
error = vget(vp, locked | LK_RETRY | LK_CANRECURSE, curthread);
|
||||
error = vget(vp, locked | LK_RETRY | LK_CANRECURSE);
|
||||
vdrop(vp);
|
||||
fs->vp = vp;
|
||||
KASSERT(error == 0, ("vm_fault: vget failed %d", error));
|
||||
|
@ -1284,7 +1284,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
|
||||
cred = td->td_ucred;
|
||||
writex = (*maxprotp & VM_PROT_WRITE) != 0 &&
|
||||
(*flagsp & MAP_SHARED) != 0;
|
||||
if ((error = vget(vp, LK_SHARED, td)) != 0)
|
||||
if ((error = vget(vp, LK_SHARED)) != 0)
|
||||
return (error);
|
||||
AUDIT_ARG_VNODE1(vp);
|
||||
foff = *foffp;
|
||||
@ -1305,7 +1305,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
|
||||
* Bypass filesystems obey the mpsafety of the
|
||||
* underlying fs. Tmpfs never bypasses.
|
||||
*/
|
||||
error = vget(vp, LK_SHARED, td);
|
||||
error = vget(vp, LK_SHARED);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
|
@ -643,7 +643,7 @@ vm_pageout_clean(vm_page_t m, int *numpagedout)
|
||||
VM_OBJECT_WUNLOCK(object);
|
||||
lockmode = MNT_SHARED_WRITES(vp->v_mount) ?
|
||||
LK_SHARED : LK_EXCLUSIVE;
|
||||
if (vget(vp, lockmode | LK_TIMELOCK, curthread)) {
|
||||
if (vget(vp, lockmode | LK_TIMELOCK)) {
|
||||
vp = NULL;
|
||||
error = EDEADLK;
|
||||
goto unlock_mp;
|
||||
|
Loading…
Reference in New Issue
Block a user