natm.c revision 192445
1139823Simp/*- 2165900Srwatson * Copyright (c) 2005-2006 Robert N. M. Watson 3165900Srwatson * All rights reserved. 425605Skjc * 5165900Srwatson * Redistribution and use in source and binary forms, with or without 6165900Srwatson * modification, are permitted provided that the following conditions 7165900Srwatson * are met: 8165900Srwatson * 1. Redistributions of source code must retain the above copyright 9165900Srwatson * notice, this list of conditions and the following disclaimer. 10165900Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11165900Srwatson * notice, this list of conditions and the following disclaimer in the 12165900Srwatson * documentation and/or other materials provided with the distribution. 13165900Srwatson * 14165900Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15165900Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16165900Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17165900Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18165900Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19165900Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20165900Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21165900Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22165900Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23165900Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24165900Srwatson * SUCH DAMAGE. 25165900Srwatson * 2625605Skjc * Copyright (c) 1996 Charles D. Cranor and Washington University. 2725605Skjc * All rights reserved. 2825605Skjc * 2925605Skjc * Redistribution and use in source and binary forms, with or without 3025605Skjc * modification, are permitted provided that the following conditions 3125605Skjc * are met: 3225605Skjc * 1. Redistributions of source code must retain the above copyright 3325605Skjc * notice, this list of conditions and the following disclaimer. 3425605Skjc * 2. Redistributions in binary form must reproduce the above copyright 3525605Skjc * notice, this list of conditions and the following disclaimer in the 3625605Skjc * documentation and/or other materials provided with the distribution. 3725605Skjc * 3. All advertising materials mentioning features or use of this software 3825605Skjc * must display the following acknowledgement: 3925605Skjc * This product includes software developed by Charles D. Cranor and 4025605Skjc * Washington University. 4125605Skjc * 4. The name of the author may not be used to endorse or promote products 4225605Skjc * derived from this software without specific prior written permission. 4325605Skjc * 4425605Skjc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4525605Skjc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4625605Skjc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 4725605Skjc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 4825605Skjc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4925605Skjc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5025605Skjc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5125605Skjc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5225605Skjc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 5325605Skjc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54165900Srwatson * 55165900Srwatson * $NetBSD: natm.c,v 1.5 1996/11/09 03:26:26 chuck Exp $ 5625605Skjc */ 5725605Skjc 5825605Skjc/* 59157985Srwatson * natm.c: Native mode ATM access (both aal0 and aal5). 6025605Skjc */ 6125605Skjc 62116189Sobrien#include <sys/cdefs.h> 63116189Sobrien__FBSDID("$FreeBSD: head/sys/netnatm/natm.c 192445 2009-05-20 17:00:16Z imp $"); 64116189Sobrien 6525605Skjc#include <sys/param.h> 6695759Stanimura#include <sys/conf.h> 6725605Skjc#include <sys/kernel.h> 6895759Stanimura#include <sys/lock.h> 6929024Sbde#include <sys/malloc.h> 7025605Skjc#include <sys/mbuf.h> 7195759Stanimura#include <sys/protosw.h> 7295759Stanimura#include <sys/signalvar.h> 7325605Skjc#include <sys/socket.h> 7425605Skjc#include <sys/socketvar.h> 7595759Stanimura#include <sys/sockio.h> 7695759Stanimura#include <sys/sx.h> 7795759Stanimura#include <sys/systm.h> 78118541Sharti#include <sys/sysctl.h> 7925605Skjc 8025605Skjc#include <net/if.h> 8125605Skjc#include <net/if_atm.h> 8225605Skjc#include <net/netisr.h> 8325605Skjc 8425605Skjc#include <netinet/in.h> 8525605Skjc 8625605Skjc#include <netnatm/natm.h> 8725605Skjc 88157985Srwatsonstatic const u_long natm5_sendspace = 16*1024; 89157985Srwatsonstatic const u_long natm5_recvspace = 16*1024; 9025605Skjc 91157985Srwatsonstatic const u_long natm0_sendspace = 16*1024; 92157985Srwatsonstatic const u_long natm0_recvspace = 16*1024; 9325605Skjc 94157985Srwatson/* 95157985Srwatson * netnatm global subsystem lock, protects all global data structures in 96157985Srwatson * netnatm. 97157985Srwatson */ 98157985Srwatsonstruct mtx natm_mtx; 99148125Srwatson 10025605Skjc/* 101157985Srwatson * User socket requests. 10225605Skjc */ 103192445Simpstatic int natm_usr_attach(struct socket *, int, struct thread *); 104157985Srwatsonstatic void natm_usr_detach(struct socket *); 105157985Srwatsonstatic int natm_usr_connect(struct socket *, struct sockaddr *, 106192445Simp struct thread *); 107157985Srwatsonstatic int natm_usr_disconnect(struct socket *); 108157985Srwatsonstatic int natm_usr_shutdown(struct socket *); 109157985Srwatsonstatic int natm_usr_send(struct socket *, int, struct mbuf *, 110192445Simp struct sockaddr *, struct mbuf *, struct thread *); 111157985Srwatsonstatic int natm_usr_peeraddr(struct socket *, struct sockaddr **); 112157985Srwatsonstatic int natm_usr_control(struct socket *, u_long, caddr_t, 113192445Simp struct ifnet *, struct thread *); 114157985Srwatsonstatic void natm_usr_abort(struct socket *); 115157985Srwatsonstatic int natm_usr_bind(struct socket *, struct sockaddr *, 116192445Simp struct thread *); 117157985Srwatsonstatic int natm_usr_sockaddr(struct socket *, struct sockaddr **); 11825605Skjc 11925605Skjcstatic int 120192445Simpnatm_usr_attach(struct socket *so, int proto, struct thread *p) 12125605Skjc{ 122157985Srwatson struct natmpcb *npcb; 123157985Srwatson int error = 0; 12425605Skjc 125157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 126157985Srwatson KASSERT(npcb == NULL, ("natm_usr_attach: so_pcb != NULL")); 12725605Skjc 128157985Srwatson if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 129157985Srwatson if (proto == PROTO_NATMAAL5) 130157985Srwatson error = soreserve(so, natm5_sendspace, 131157985Srwatson natm5_recvspace); 132157985Srwatson else 133157985Srwatson error = soreserve(so, natm0_sendspace, 134157985Srwatson natm0_recvspace); 135157985Srwatson if (error) 136157985Srwatson return (error); 137157985Srwatson } 138157985Srwatson so->so_pcb = npcb = npcb_alloc(M_WAITOK); 139157985Srwatson npcb->npcb_socket = so; 140157985Srwatson return (error); 14125605Skjc} 14225605Skjc 143157370Srwatsonstatic void 14425605Skjcnatm_usr_detach(struct socket *so) 14525605Skjc{ 146157985Srwatson struct natmpcb *npcb; 14725605Skjc 148157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 149157985Srwatson KASSERT(npcb != NULL, ("natm_usr_detach: npcb == NULL")); 150157983Srwatson 151157985Srwatson NATM_LOCK(); 152157985Srwatson npcb_free(npcb, NPCB_DESTROY); /* drain */ 153157985Srwatson so->so_pcb = NULL; 154157985Srwatson NATM_UNLOCK(); 15525605Skjc} 15625605Skjc 15725605Skjcstatic int 158192445Simpnatm_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *p) 15925605Skjc{ 160157985Srwatson struct natmpcb *npcb; 161157985Srwatson struct sockaddr_natm *snatm; 162157985Srwatson struct atmio_openvcc op; 163157985Srwatson struct ifnet *ifp; 164157985Srwatson int error = 0; 165157985Srwatson int proto = so->so_proto->pr_protocol; 16625605Skjc 167157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 168157985Srwatson KASSERT(npcb != NULL, ("natm_usr_connect: npcb == NULL")); 16925605Skjc 170157985Srwatson /* 171157985Srwatson * Validate nam and npcb. 172157985Srwatson */ 173157985Srwatson NATM_LOCK(); 174157985Srwatson snatm = (struct sockaddr_natm *)nam; 175157985Srwatson if (snatm->snatm_len != sizeof(*snatm) || 176157985Srwatson (npcb->npcb_flags & NPCB_FREE) == 0) { 177157985Srwatson NATM_UNLOCK(); 178157985Srwatson return (EINVAL); 179157985Srwatson } 180157985Srwatson if (snatm->snatm_family != AF_NATM) { 181157985Srwatson NATM_UNLOCK(); 182157985Srwatson return (EAFNOSUPPORT); 183157985Srwatson } 18425605Skjc 185157985Srwatson snatm->snatm_if[IFNAMSIZ - 1] = '\0'; /* XXX ensure null termination 186118541Sharti since ifunit() uses strcmp */ 18725605Skjc 188157985Srwatson /* 189157985Srwatson * Convert interface string to ifp, validate. 190157985Srwatson */ 191157985Srwatson ifp = ifunit(snatm->snatm_if); 192157985Srwatson if (ifp == NULL || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 193157985Srwatson NATM_UNLOCK(); 194157985Srwatson return (ENXIO); 195157985Srwatson } 196157985Srwatson if (ifp->if_output != atm_output) { 197157985Srwatson NATM_UNLOCK(); 198157985Srwatson return (EAFNOSUPPORT); 199157985Srwatson } 20025605Skjc 201157985Srwatson /* 202157985Srwatson * Register us with the NATM PCB layer. 203157985Srwatson */ 204157985Srwatson if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb) { 205157985Srwatson NATM_UNLOCK(); 206157985Srwatson return (EADDRINUSE); 207157985Srwatson } 208157985Srwatson 209157985Srwatson /* 210157985Srwatson * Open the channel. 211157985Srwatson * 212157985Srwatson * XXXRW: Eventually desirable to hold mutex over ioctl? 213157985Srwatson */ 214157985Srwatson bzero(&op, sizeof(op)); 215157985Srwatson op.rxhand = npcb; 216157985Srwatson op.param.flags = ATMIO_FLAG_PVC; 217157985Srwatson op.param.vpi = npcb->npcb_vpi; 218157985Srwatson op.param.vci = npcb->npcb_vci; 219157985Srwatson op.param.rmtu = op.param.tmtu = ifp->if_mtu; 220157985Srwatson op.param.aal = (proto == PROTO_NATMAAL5) ? ATMIO_AAL_5 : ATMIO_AAL_0; 221157985Srwatson op.param.traffic = ATMIO_TRAFFIC_UBR; 222157984Srwatson NATM_UNLOCK(); 22325605Skjc 224157985Srwatson if (ifp->if_ioctl == NULL || 225189851Srwatson ifp->if_ioctl(ifp, SIOCATMOPENVCC, (caddr_t)&op) != 0) 226157985Srwatson return (EIO); 227157985Srwatson soisconnected(so); 228157985Srwatson return (error); 22925605Skjc} 23025605Skjc 23125605Skjcstatic int 23225605Skjcnatm_usr_disconnect(struct socket *so) 23325605Skjc{ 234157985Srwatson struct natmpcb *npcb; 235157985Srwatson struct atmio_closevcc cl; 236157985Srwatson struct ifnet *ifp; 237157985Srwatson int error = 0; 23825605Skjc 239157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 240157985Srwatson KASSERT(npcb != NULL, ("natm_usr_disconnect: npcb == NULL")); 24125605Skjc 242157985Srwatson NATM_LOCK(); 243157985Srwatson if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) { 244157985Srwatson NATM_UNLOCK(); 245157985Srwatson printf("natm: disconnected check\n"); 246157985Srwatson return (EIO); 247157985Srwatson } 248157985Srwatson ifp = npcb->npcb_ifp; 249157985Srwatson 250157985Srwatson /* 251157985Srwatson * Disable rx. 252157985Srwatson * 253157985Srwatson * XXXRW: Eventually desirable to hold mutex over ioctl? 254157985Srwatson */ 255157985Srwatson cl.vpi = npcb->npcb_vpi; 256157985Srwatson cl.vci = npcb->npcb_vci; 257157984Srwatson NATM_UNLOCK(); 258189851Srwatson if (ifp->if_ioctl != NULL) 259157985Srwatson ifp->if_ioctl(ifp, SIOCATMCLOSEVCC, (caddr_t)&cl); 260157985Srwatson soisdisconnected(so); 261157985Srwatson return (error); 26225605Skjc} 26325605Skjc 26425605Skjcstatic int 26525605Skjcnatm_usr_shutdown(struct socket *so) 26625605Skjc{ 267157985Srwatson 268157985Srwatson socantsendmore(so); 269157985Srwatson return (0); 27025605Skjc} 27125605Skjc 27225605Skjcstatic int 27328270Swollmannatm_usr_send(struct socket *so, int flags, struct mbuf *m, 274192445Simp struct sockaddr *nam, struct mbuf *control, struct thread *p) 27525605Skjc{ 276157985Srwatson struct natmpcb *npcb; 277157985Srwatson struct atm_pseudohdr *aph; 278157985Srwatson int error = 0; 279157985Srwatson int proto = so->so_proto->pr_protocol; 28025605Skjc 281157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 282157985Srwatson KASSERT(npcb != NULL, ("natm_usr_send: npcb == NULL")); 28325605Skjc 284157985Srwatson NATM_LOCK(); 285157985Srwatson if (control && control->m_len) { 286157985Srwatson NATM_UNLOCK(); 287157985Srwatson m_freem(control); 288157985Srwatson m_freem(m); 289157985Srwatson return (EINVAL); 290157985Srwatson } 29125605Skjc 292157985Srwatson /* 293157985Srwatson * Send the data. We must put an atm_pseudohdr on first. 294157985Srwatson */ 295157985Srwatson M_PREPEND(m, sizeof(*aph), M_DONTWAIT); 296157985Srwatson if (m == NULL) { 297157985Srwatson NATM_UNLOCK(); 298157985Srwatson m_freem(control); 299157985Srwatson return (ENOBUFS); 300157985Srwatson } 301157985Srwatson aph = mtod(m, struct atm_pseudohdr *); 302157985Srwatson ATM_PH_VPI(aph) = npcb->npcb_vpi; 303157985Srwatson ATM_PH_SETVCI(aph, npcb->npcb_vci); 304157985Srwatson ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; 305157985Srwatson error = atm_output(npcb->npcb_ifp, m, NULL, NULL); 306157984Srwatson NATM_UNLOCK(); 307157985Srwatson return (error); 30825605Skjc} 30925605Skjc 31025605Skjcstatic int 31128270Swollmannatm_usr_peeraddr(struct socket *so, struct sockaddr **nam) 31225605Skjc{ 313157985Srwatson struct natmpcb *npcb; 314157985Srwatson struct sockaddr_natm *snatm, ssnatm; 31525605Skjc 316157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 317157985Srwatson KASSERT(npcb != NULL, ("natm_usr_peeraddr: npcb == NULL")); 31825605Skjc 319157985Srwatson NATM_LOCK(); 320157985Srwatson snatm = &ssnatm; 321157985Srwatson bzero(snatm, sizeof(*snatm)); 322157985Srwatson snatm->snatm_len = sizeof(*snatm); 323157985Srwatson snatm->snatm_family = AF_NATM; 324157985Srwatson strlcpy(snatm->snatm_if, npcb->npcb_ifp->if_xname, 325157985Srwatson sizeof(snatm->snatm_if)); 326157985Srwatson snatm->snatm_vci = npcb->npcb_vci; 327157985Srwatson snatm->snatm_vpi = npcb->npcb_vpi; 328157985Srwatson NATM_UNLOCK(); 329157985Srwatson *nam = sodupsockaddr((struct sockaddr *)snatm, M_WAITOK); 330157985Srwatson return (0); 33125605Skjc} 33225605Skjc 33325605Skjcstatic int 33436735Sdfrnatm_usr_control(struct socket *so, u_long cmd, caddr_t arg, 335192445Simp struct ifnet *ifp, struct thread *p) 33625605Skjc{ 337157985Srwatson struct natmpcb *npcb; 33825605Skjc 339157985Srwatson npcb = (struct natmpcb *)so->so_pcb; 340157985Srwatson KASSERT(npcb != NULL, ("natm_usr_control: npcb == NULL")); 34125605Skjc 342157985Srwatson if (ifp == NULL || ifp->if_ioctl == NULL) 343157985Srwatson return (EOPNOTSUPP); 344189851Srwatson return ((*ifp->if_ioctl)(ifp, cmd, arg)); 34525605Skjc} 34625605Skjc 347157366Srwatsonstatic void 34825605Skjcnatm_usr_abort(struct socket *so) 34925605Skjc{ 350157985Srwatson 35125605Skjc} 35225605Skjc 353160549Srwatsonstatic void 354160549Srwatsonnatm_usr_close(struct socket *so) 355160549Srwatson{ 356160549Srwatson 357160549Srwatson} 358160549Srwatson 35925605Skjcstatic int 360192445Simpnatm_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *p) 36125605Skjc{ 362157985Srwatson 363157985Srwatson return (EOPNOTSUPP); 36425605Skjc} 36525605Skjc 36625605Skjcstatic int 36728270Swollmannatm_usr_sockaddr(struct socket *so, struct sockaddr **nam) 36825605Skjc{ 369157985Srwatson 370157985Srwatson return (EOPNOTSUPP); 37125605Skjc} 37225605Skjc 37325605Skjc/* xxx - should be const */ 37425605Skjcstruct pr_usrreqs natm_usrreqs = { 375137386Sphk .pru_abort = natm_usr_abort, 376137386Sphk .pru_attach = natm_usr_attach, 377137386Sphk .pru_bind = natm_usr_bind, 378137386Sphk .pru_connect = natm_usr_connect, 379137386Sphk .pru_control = natm_usr_control, 380137386Sphk .pru_detach = natm_usr_detach, 381137386Sphk .pru_disconnect = natm_usr_disconnect, 382137386Sphk .pru_peeraddr = natm_usr_peeraddr, 383137386Sphk .pru_send = natm_usr_send, 384137386Sphk .pru_shutdown = natm_usr_shutdown, 385137386Sphk .pru_sockaddr = natm_usr_sockaddr, 386160549Srwatson .pru_close = natm_usr_close, 38725605Skjc}; 38825605Skjc 38925605Skjc/* 390148158Srwatson * natmintr: interrupt 39125605Skjc * 392157985Srwatson * Note: we expect a socket pointer in rcvif rather than an interface 393157985Srwatson * pointer. We can get the interface pointer from the so's PCB if we really 394157985Srwatson * need it. 39525605Skjc */ 39625605Skjcvoid 397111888Sjlemonnatmintr(struct mbuf *m) 39825605Skjc{ 399118541Sharti struct socket *so; 400118541Sharti struct natmpcb *npcb; 40125605Skjc 40225605Skjc#ifdef DIAGNOSTIC 403118541Sharti M_ASSERTPKTHDR(m); 40425605Skjc#endif 40525605Skjc 406148125Srwatson NATM_LOCK(); 407118541Sharti npcb = (struct natmpcb *)m->m_pkthdr.rcvif; /* XXX: overloaded */ 408118541Sharti so = npcb->npcb_socket; 40925605Skjc 410118541Sharti npcb->npcb_inq--; 41125605Skjc 412118541Sharti if (npcb->npcb_flags & NPCB_DRAIN) { 413118541Sharti if (npcb->npcb_inq == 0) 414184205Sdes free(npcb, M_PCB); /* done! */ 415148125Srwatson NATM_UNLOCK(); 416148125Srwatson m_freem(m); 417118541Sharti return; 418118541Sharti } 41925605Skjc 420118541Sharti if (npcb->npcb_flags & NPCB_FREE) { 421148125Srwatson NATM_UNLOCK(); 422118541Sharti m_freem(m); /* drop */ 423118541Sharti return; 424118541Sharti } 42525605Skjc 42625605Skjc#ifdef NEED_TO_RESTORE_IFP 427118541Sharti m->m_pkthdr.rcvif = npcb->npcb_ifp; 42825605Skjc#else 42925605Skjc#ifdef DIAGNOSTIC 430118541Sharti m->m_pkthdr.rcvif = NULL; /* null it out to be safe */ 43125605Skjc#endif 43225605Skjc#endif 43325605Skjc 434118547Sharti if (sbspace(&so->so_rcv) > m->m_pkthdr.len) { 43525605Skjc#ifdef NATM_STAT 436118541Sharti natm_sookcnt++; 437118541Sharti natm_sookbytes += m->m_pkthdr.len; 43825605Skjc#endif 439118541Sharti sbappendrecord(&so->so_rcv, m); 440118541Sharti sorwakeup(so); 441148125Srwatson NATM_UNLOCK(); 442118541Sharti } else { 44325605Skjc#ifdef NATM_STAT 444118541Sharti natm_sodropcnt++; 445118541Sharti natm_sodropbytes += m->m_pkthdr.len; 44625605Skjc#endif 447148125Srwatson NATM_UNLOCK(); 448118541Sharti m_freem(m); 449118541Sharti } 45025605Skjc} 45125605Skjc 45225605Skjc/* 45325605Skjc * natm0_sysctl: not used, but here in case we want to add something 45425605Skjc * later... 45525605Skjc */ 456118541Shartiint 457118541Shartinatm0_sysctl(SYSCTL_HANDLER_ARGS) 45825605Skjc{ 459157985Srwatson 460118541Sharti /* All sysctl names at this level are terminal. */ 461118541Sharti return (ENOENT); 46225605Skjc} 46325605Skjc 46425605Skjc/* 46525605Skjc * natm5_sysctl: not used, but here in case we want to add something 46625605Skjc * later... 46725605Skjc */ 468118541Shartiint 469118541Shartinatm5_sysctl(SYSCTL_HANDLER_ARGS) 47025605Skjc{ 471157985Srwatson 472118541Sharti /* All sysctl names at this level are terminal. */ 473118541Sharti return (ENOENT); 47425605Skjc} 475