b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * CDDL HEADER START
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk *
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * The contents of this file are subject to the terms of the
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Common Development and Distribution License (the "License").
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * You may not use this file except in compliance with the License.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk *
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * or http://www.opensolaris.org/os/licensing.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * See the License for the specific language governing permissions
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * and limitations under the License.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk *
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * When distributing Covered Code, include this CDDL HEADER in each
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * If applicable, add the following below this CDDL HEADER, with the
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * fields enclosed by brackets "[]" replaced with your own identifying
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * information: Portions Copyright [yyyy] [name of copyright owner]
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk *
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * CDDL HEADER END
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Use is subject to license terms.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * vnode ops for the /dev/ipnet directory
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * The lookup is based on the ipnetif nodes held
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * in the ipnet module. We also override readdir
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * in order to delete ipnet nodes no longer in use.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/types.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/param.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/sysmacros.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/sunndi.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <fs/fs_subr.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/fs/dv_node.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/fs/sdev_impl.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/policy.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <inet/ipnet.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk#include <sys/zone.h>
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstruct vnodeops *devipnet_vnodeops;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic void
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_fill_vattr(struct vattr *vap, dev_t dev)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk timestruc_t now;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk *vap = sdev_vattr_chr;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk vap->va_rdev = dev;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk vap->va_mode |= 0666;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk gethrestime(&now);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk vap->va_atime = now;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk vap->va_mtime = now;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk vap->va_ctime = now;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Check if an ipnet sdev_node is still valid.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkint
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_validate(struct sdev_node *dv)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk dev_t dev;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk dev = ipnet_if_getdev(dv->sdev_name, getzoneid());
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (dev == (dev_t)-1)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (SDEV_VTOR_INVALID);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (getminor(SDEVTOV(dv)->v_rdev) != getminor(dev))
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (SDEV_VTOR_STALE);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (SDEV_VTOR_VALID);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * This callback is invoked from devname_lookup_func() to create
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * an ipnet entry when the node is not found in the cache.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*ARGSUSED*/
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic int
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_create_rvp(struct sdev_node *ddv, char *nm,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk void **arg, cred_t *cred, void *whatever, char *whichever)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk dev_t dev;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct vattr *vap = (struct vattr *)arg;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk int err = 0;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if ((dev = ipnet_if_getdev(nm, getzoneid())) == (dev_t)-1)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk err = ENOENT;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk else
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk devipnet_fill_vattr(vap, dev);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (err);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Lookup for /dev/ipnet directory
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * If the entry does not exist, the devipnet_create_rvp() callback
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * is invoked to create it. Nodes do not persist across reboot.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*ARGSUSED3*/
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic int
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cred,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk caller_context_t *ct, int *direntflags, pathname_t *realpnp)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct sdev_node *sdvp = VTOSDEV(dvp);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct sdev_node *dv;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct vnode *rvp = NULL;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk int error;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk error = devname_lookup_func(sdvp, nm, vpp, cred, devipnet_create_rvp,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk SDEV_VATTR);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (error == 0) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk switch ((*vpp)->v_type) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case VCHR:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk dv = VTOSDEV(VTOS(*vpp)->s_realvp);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk ASSERT(VOP_REALVP(SDEVTOV(dv), &rvp, NULL) == ENOSYS);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk break;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case VDIR:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk dv = VTOSDEV(*vpp);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk break;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk default:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk cmn_err(CE_PANIC, "devipnet_lookup: Unsupported node "
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk "type: %p: %d", (void *)(*vpp), (*vpp)->v_type);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk break;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk ASSERT(SDEV_HELD(dv));
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (error);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic void
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_filldir_entry(const char *name, void *arg, dev_t dev)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct sdev_node *ddv = arg;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct vattr vattr;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct sdev_node *dv;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if ((dv = sdev_cache_lookup(ddv, (char *)name)) == NULL) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk devipnet_fill_vattr(&vattr, dev);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (sdev_mknode(ddv, (char *)name, &dv, &vattr, NULL, NULL,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk kcred, SDEV_READY) != 0)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk SDEV_SIMPLE_RELE(dv);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic void
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_filldir(struct sdev_node *ddv)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk sdev_node_t *dv, *next;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk ASSERT(RW_READ_HELD(&ddv->sdev_contents));
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (rw_tryupgrade(&ddv->sdev_contents) == NULL) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk rw_exit(&ddv->sdev_contents);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk rw_enter(&ddv->sdev_contents, RW_WRITER);
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi /*
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi * We've been made a zombie while we weren't looking. We'll bail
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi * if that's the case.
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi */
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi if (ddv->sdev_state == SDEV_ZOMBIE) {
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi rw_exit(&ddv->sdev_contents);
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi return;
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk next = SDEV_NEXT_ENTRY(ddv, dv);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk /* validate and prune only ready nodes */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (dv->sdev_state != SDEV_READY)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk continue;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk switch (devipnet_validate(dv)) {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case SDEV_VTOR_VALID:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case SDEV_VTOR_SKIP:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk continue;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case SDEV_VTOR_INVALID:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk case SDEV_VTOR_STALE:
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk sdcmn_err12(("devipnet_filldir: destroy invalid "
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk "node: %s(%p)\n", dv->sdev_name, (void *)dv));
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk break;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (SDEVTOV(dv)->v_count > 0)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk continue;
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk SDEV_HOLD(dv);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk /* remove the cache node */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk (void) sdev_cache_update(ddv, &dv, dv->sdev_name,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk SDEV_CACHE_DELETE);
9e5aa9d8a21f8efa8ba9c9e4a0aa6edc66d07eb2Robert Mustacchi SDEV_RELE(dv);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk }
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk ipnet_walk_if(devipnet_filldir_entry, ddv, getzoneid());
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk rw_downgrade(&ddv->sdev_contents);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * Display all instantiated ipnet device nodes.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/* ARGSUSED */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkstatic int
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkdevipnet_readdir(struct vnode *dvp, struct uio *uiop, struct cred *cred,
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk int *eofp, caller_context_t *ct, int flags)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk{
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk struct sdev_node *sdvp = VTOSDEV(dvp);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk if (uiop->uio_offset == 0)
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk devipnet_filldir(sdvp);
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk}
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk/*
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * We override lookup and readdir to build entries based on the
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk * in kernel ipnet table.
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk */
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirkconst fs_operation_def_t devipnet_vnodeops_tbl[] = {
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_READDIR, { .vop_readdir = devipnet_readdir },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_LOOKUP, { .vop_lookup = devipnet_lookup },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_CREATE, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_REMOVE, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_MKDIR, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_RMDIR, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_SYMLINK, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk VOPNAME_SETSECATTR, { .error = fs_nosys },
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk NULL, NULL
b127ac411761a3d8d642d9342d9cac2785e1faaaPhilip Kirk};