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$"); 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 */ 295243882Sglebius M_PREPEND(m, sizeof(*aph), M_NOWAIT); 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 342255442Sdes switch (cmd) { 343255442Sdes case SIOCSIFADDR: 344255442Sdes case SIOCSIFBRDADDR: 345255442Sdes case SIOCSIFDSTADDR: 346255442Sdes case SIOCSIFNETMASK: 347255442Sdes /* 348255442Sdes * Although we should pass any non-ATM ioctl requests 349255442Sdes * down to driver, we filter some legacy INET requests. 350255442Sdes * Drivers trust SIOCSIFADDR et al to come from an already 351255442Sdes * privileged layer, and do not perform any credentials 352255442Sdes * checks or input validation. 353255442Sdes */ 354255442Sdes return (EINVAL); 355255442Sdes } 356255442Sdes 357157985Srwatson if (ifp == NULL || ifp->if_ioctl == NULL) 358157985Srwatson return (EOPNOTSUPP); 359189851Srwatson return ((*ifp->if_ioctl)(ifp, cmd, arg)); 36025605Skjc} 36125605Skjc 362157366Srwatsonstatic void 36325605Skjcnatm_usr_abort(struct socket *so) 36425605Skjc{ 365157985Srwatson 36625605Skjc} 36725605Skjc 368160549Srwatsonstatic void 369160549Srwatsonnatm_usr_close(struct socket *so) 370160549Srwatson{ 371160549Srwatson 372160549Srwatson} 373160549Srwatson 37425605Skjcstatic int 375192445Simpnatm_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *p) 37625605Skjc{ 377157985Srwatson 378157985Srwatson return (EOPNOTSUPP); 37925605Skjc} 38025605Skjc 38125605Skjcstatic int 38228270Swollmannatm_usr_sockaddr(struct socket *so, struct sockaddr **nam) 38325605Skjc{ 384157985Srwatson 385157985Srwatson return (EOPNOTSUPP); 38625605Skjc} 38725605Skjc 38825605Skjc/* xxx - should be const */ 38925605Skjcstruct pr_usrreqs natm_usrreqs = { 390137386Sphk .pru_abort = natm_usr_abort, 391137386Sphk .pru_attach = natm_usr_attach, 392137386Sphk .pru_bind = natm_usr_bind, 393137386Sphk .pru_connect = natm_usr_connect, 394137386Sphk .pru_control = natm_usr_control, 395137386Sphk .pru_detach = natm_usr_detach, 396137386Sphk .pru_disconnect = natm_usr_disconnect, 397137386Sphk .pru_peeraddr = natm_usr_peeraddr, 398137386Sphk .pru_send = natm_usr_send, 399137386Sphk .pru_shutdown = natm_usr_shutdown, 400137386Sphk .pru_sockaddr = natm_usr_sockaddr, 401160549Srwatson .pru_close = natm_usr_close, 40225605Skjc}; 40325605Skjc 40425605Skjc/* 405148158Srwatson * natmintr: interrupt 40625605Skjc * 407157985Srwatson * Note: we expect a socket pointer in rcvif rather than an interface 408157985Srwatson * pointer. We can get the interface pointer from the so's PCB if we really 409157985Srwatson * need it. 41025605Skjc */ 41125605Skjcvoid 412111888Sjlemonnatmintr(struct mbuf *m) 41325605Skjc{ 414118541Sharti struct socket *so; 415118541Sharti struct natmpcb *npcb; 41625605Skjc 41725605Skjc#ifdef DIAGNOSTIC 418118541Sharti M_ASSERTPKTHDR(m); 41925605Skjc#endif 42025605Skjc 421148125Srwatson NATM_LOCK(); 422118541Sharti npcb = (struct natmpcb *)m->m_pkthdr.rcvif; /* XXX: overloaded */ 423118541Sharti so = npcb->npcb_socket; 42425605Skjc 425118541Sharti npcb->npcb_inq--; 42625605Skjc 427118541Sharti if (npcb->npcb_flags & NPCB_DRAIN) { 428118541Sharti if (npcb->npcb_inq == 0) 429184205Sdes free(npcb, M_PCB); /* done! */ 430148125Srwatson NATM_UNLOCK(); 431148125Srwatson m_freem(m); 432118541Sharti return; 433118541Sharti } 43425605Skjc 435118541Sharti if (npcb->npcb_flags & NPCB_FREE) { 436148125Srwatson NATM_UNLOCK(); 437118541Sharti m_freem(m); /* drop */ 438118541Sharti return; 439118541Sharti } 44025605Skjc 44125605Skjc#ifdef NEED_TO_RESTORE_IFP 442118541Sharti m->m_pkthdr.rcvif = npcb->npcb_ifp; 44325605Skjc#else 44425605Skjc#ifdef DIAGNOSTIC 445118541Sharti m->m_pkthdr.rcvif = NULL; /* null it out to be safe */ 44625605Skjc#endif 44725605Skjc#endif 44825605Skjc 449118547Sharti if (sbspace(&so->so_rcv) > m->m_pkthdr.len) { 45025605Skjc#ifdef NATM_STAT 451118541Sharti natm_sookcnt++; 452118541Sharti natm_sookbytes += m->m_pkthdr.len; 45325605Skjc#endif 454118541Sharti sbappendrecord(&so->so_rcv, m); 455118541Sharti sorwakeup(so); 456148125Srwatson NATM_UNLOCK(); 457118541Sharti } else { 45825605Skjc#ifdef NATM_STAT 459118541Sharti natm_sodropcnt++; 460118541Sharti natm_sodropbytes += m->m_pkthdr.len; 46125605Skjc#endif 462148125Srwatson NATM_UNLOCK(); 463118541Sharti m_freem(m); 464118541Sharti } 46525605Skjc} 46625605Skjc 46725605Skjc/* 46825605Skjc * natm0_sysctl: not used, but here in case we want to add something 46925605Skjc * later... 47025605Skjc */ 471118541Shartiint 472118541Shartinatm0_sysctl(SYSCTL_HANDLER_ARGS) 47325605Skjc{ 474157985Srwatson 475118541Sharti /* All sysctl names at this level are terminal. */ 476118541Sharti return (ENOENT); 47725605Skjc} 47825605Skjc 47925605Skjc/* 48025605Skjc * natm5_sysctl: not used, but here in case we want to add something 48125605Skjc * later... 48225605Skjc */ 483118541Shartiint 484118541Shartinatm5_sysctl(SYSCTL_HANDLER_ARGS) 48525605Skjc{ 486157985Srwatson 487118541Sharti /* All sysctl names at this level are terminal. */ 488118541Sharti return (ENOENT); 48925605Skjc} 490