47#include <sys/dirent.h>
49#include <sys/kernel.h>
51#include <sys/malloc.h>
55#include <sys/rmlock.h>
56#include <sys/refcount.h>
57#include <sys/signalvar.h>
58#include <sys/socket.h>
61#include <netinet/in.h>
67static MALLOC_DEFINE(M_NETADDR,
"export_host",
"Export host address structure");
69#if defined(INET) || defined(INET6)
70static struct radix_node_head *vfs_create_addrlist_af(
71 struct radix_node_head **prnh,
int off);
77 struct export_args *argp);
96 struct radix_node_head *
ne4;
97 struct radix_node_head *
ne6;
106 struct export_args *argp)
109 struct radix_node_head *rnh;
111 struct radix_node *rn;
112 struct sockaddr *saddr, *smask = NULL;
113#if defined(INET6) || defined(INET)
118 KASSERT(argp->ex_numsecflavors > 0,
119 (
"%s: numsecflavors <= 0", __func__));
120 KASSERT(argp->ex_numsecflavors < MAXSECFLAVORS,
121 (
"%s: numsecflavors >= MAXSECFLAVORS", __func__));
130 if (argp->ex_addrlen == 0) {
131 if (mp->mnt_flag & MNT_DEFEXPORTED) {
133 "MNT_DEFEXPORTED already set for mount %p", mp);
148 mp->mnt_flag |= MNT_DEFEXPORTED;
154 if (argp->ex_addrlen > MLEN) {
156 argp->ex_addrlen, MLEN);
161 i =
sizeof(
struct netcred) + argp->ex_addrlen + argp->ex_masklen;
162 np = (
struct netcred *)
malloc(i, M_NETADDR, M_WAITOK | M_ZERO);
163 saddr = (
struct sockaddr *) (np + 1);
164 if ((error = copyin(argp->ex_addr, saddr, argp->ex_addrlen)))
166 if (saddr->sa_family == AF_UNSPEC || saddr->sa_family > AF_MAX) {
171 if (saddr->sa_len > argp->ex_addrlen)
172 saddr->sa_len = argp->ex_addrlen;
173 if (argp->ex_masklen) {
174 smask = (
struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen);
175 error = copyin(argp->ex_mask, smask, argp->ex_masklen);
178 if (smask->sa_len > argp->ex_masklen)
179 smask->sa_len = argp->ex_masklen;
182 switch (saddr->sa_family) {
185 if ((rnh = nep->
ne4) == NULL) {
186 off = offsetof(
struct sockaddr_in, sin_addr) << 3;
187 rnh = vfs_create_addrlist_af(&nep->
ne4, off);
193 if ((rnh = nep->
ne6) == NULL) {
194 off = offsetof(
struct sockaddr_in6, sin6_addr) << 3;
195 rnh = vfs_create_addrlist_af(&nep->
ne6, off);
203 "Unable to initialize radix node head ",
204 "for address family", saddr->sa_family);
207 RADIX_NODE_HEAD_LOCK(rnh);
208 rn = (*rnh->rnh_addaddr)(saddr, smask, &rnh->rh, np->
netc_rnodes);
209 RADIX_NODE_HEAD_UNLOCK(rnh);
210 if (rn == NULL || np != (
struct netcred *)rn) {
213 "netcred already exists for given addr/mask");
237 struct radix_node_head *rnh = (
struct radix_node_head *) w;
240 (*rnh->rnh_deladdr) (rn->rn_key, rn->rn_mask, &rnh->rh);
241 cred = ((
struct netcred *)rn)->netc_anon;
248#if defined(INET) || defined(INET6)
249static struct radix_node_head *
250vfs_create_addrlist_af(
struct radix_node_head **prnh,
int off)
253 if (rn_inithead((
void **)prnh, off) == 0)
255 RADIX_NODE_HEAD_LOCK_INIT(*prnh);
263 struct radix_node_head *rnh;
266 RADIX_NODE_HEAD_LOCK(rnh);
268 RADIX_NODE_HEAD_UNLOCK(rnh);
269 RADIX_NODE_HEAD_DESTROY(rnh);
270 rn_detachhead((
void **)prnh);
282 if (nep->
ne4 != NULL)
284 if (nep->
ne6 != NULL)
305 if ((argp->ex_flags & (MNT_DELEXPORT | MNT_EXPORTED)) == 0)
308 if ((argp->ex_flags & MNT_EXPORTED) != 0 &&
309 (argp->ex_numsecflavors < 0
310 || argp->ex_numsecflavors >= MAXSECFLAVORS))
314 lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL);
315 nep = mp->mnt_export;
316 if (argp->ex_flags & MNT_DELEXPORT) {
321 if (mp->mnt_flag & MNT_EXPUBLIC) {
324 mp->mnt_flag &= ~MNT_EXPUBLIC;
328 mp->mnt_export = NULL;
332 mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED);
335 if (argp->ex_flags & MNT_EXPORTED) {
338 mp->mnt_export = nep;
340 if (argp->ex_flags & MNT_EXPUBLIC) {
344 mp->mnt_flag |= MNT_EXPUBLIC;
347 if (argp->ex_numsecflavors == 0) {
348 argp->ex_numsecflavors = 1;
349 argp->ex_secflavors[0] = AUTH_SYS;
354 mp->mnt_flag |= MNT_EXPORTED;
359 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
379 struct export_args *argp)
391 if (nfs_pub.np_valid) {
392 nfs_pub.np_valid = 0;
393 if (nfs_pub.np_index != NULL) {
394 free(nfs_pub.np_index, M_TEMP);
395 nfs_pub.np_index = NULL;
404 if (nfs_pub.np_valid != 0 && mp != nfs_pub.np_mount)
410 bzero(&nfs_pub.np_handle,
sizeof(nfs_pub.np_handle));
411 nfs_pub.np_handle.fh_fsid = mp->mnt_stat.f_fsid;
413 if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp)))
416 if ((error = VOP_VPTOFH(rvp, &nfs_pub.np_handle.fh_fid)))
424 if (argp->ex_indexfile != NULL) {
425 if (nfs_pub.np_index == NULL)
426 nfs_pub.np_index =
malloc(MAXNAMLEN + 1, M_TEMP,
428 error = copyinstr(argp->ex_indexfile, nfs_pub.np_index,
429 MAXNAMLEN, (
size_t *)0);
434 for (cp = nfs_pub.np_index; *cp; cp++) {
442 free(nfs_pub.np_index, M_TEMP);
443 nfs_pub.np_index = NULL;
448 nfs_pub.np_mount = mp;
449 nfs_pub.np_valid = 1;
462 RADIX_NODE_HEAD_RLOCK_TRACKER;
465 struct radix_node_head *rnh;
466 struct sockaddr *saddr;
468 nep = mp->mnt_export;
471 if ((mp->mnt_flag & MNT_EXPORTED) == 0)
480 switch (saddr->sa_family) {
489 RADIX_NODE_HEAD_RLOCK(rnh);
490 np = (
struct netcred *) (*rnh->rnh_matchaddr)(saddr, &rnh->rh);
491 RADIX_NODE_HEAD_RUNLOCK(rnh);
492 if (np != NULL && (np->
netc_rnodes->rn_flags & RNF_ROOT) != 0)
500 if (np == NULL && (mp->mnt_flag & MNT_DEFEXPORTED) != 0)
517 struct ucred **credanonp,
int *numsecflavors,
int *secflavors)
521 lockmgr(&mp->mnt_explock, LK_SHARED, NULL);
524 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
529 if ((*credanonp = np->
netc_anon) != NULL)
533 KASSERT(*numsecflavors > 0,
534 (
"%s: numsecflavors <= 0", __func__));
535 KASSERT(*numsecflavors < MAXSECFLAVORS,
536 (
"%s: numsecflavors >= MAXSECFLAVORS", __func__));
541 lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
void prison_hold(struct prison *pr)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
struct ucred * crget(void)
struct ucred * crhold(struct ucred *cr)
void crfree(struct ucred *cr)
void crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
int netc_secflavors[MAXSECFLAVORS]
struct radix_node netc_rnodes[2]
struct radix_node_head * ne6
struct netcred ne_defexported
struct radix_node_head * ne4
static int vfs_free_netcred(struct radix_node *rn, void *w)
int vfs_export(struct mount *mp, struct export_args *argp)
static MALLOC_DEFINE(M_NETADDR, "export_host", "Export host address structure")
int vfs_setpublicfs(struct mount *mp, struct netexport *nep, struct export_args *argp)
static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep, struct export_args *argp)
int vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp, struct ucred **credanonp, int *numsecflavors, int *secflavors)
static struct netcred * vfs_export_lookup(struct mount *, struct sockaddr *)
static void vfs_free_addrlist(struct netexport *nep)
static void vfs_free_addrlist_af(struct radix_node_head **prnh)
void vfs_mount_error(struct mount *mp, const char *fmt,...)
void vfs_deleteopt(struct vfsoptlist *opts, const char *name)
void vput(struct vnode *vp)