Annotation of src/sys/net/if_tap.c, Revision 1.47.4.3
1.47.4.3! snj 1: /* $NetBSD: if_tap.c,v 1.47.4.2 2008/11/19 03:40:27 snj Exp $ */
1.1 cube 2:
3: /*
1.41 ad 4: * Copyright (c) 2003, 2004, 2008 The NetBSD Foundation.
1.1 cube 5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.6 perry 15: *
1.1 cube 16: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26: * POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: /*
30: * tap(4) is a virtual Ethernet interface. It appears as a real Ethernet
31: * device to the system, but can also be accessed by userland through a
32: * character device interface, which allows reading and injecting frames.
33: */
34:
35: #include <sys/cdefs.h>
1.47.4.3! snj 36: __KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.47.4.2 2008/11/19 03:40:27 snj Exp $");
1.1 cube 37:
1.2 cube 38: #if defined(_KERNEL_OPT)
1.1 cube 39: #include "bpfilter.h"
1.2 cube 40: #endif
1.1 cube 41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/kernel.h>
45: #include <sys/malloc.h>
46: #include <sys/conf.h>
47: #include <sys/device.h>
48: #include <sys/file.h>
49: #include <sys/filedesc.h>
50: #include <sys/ksyms.h>
51: #include <sys/poll.h>
52: #include <sys/select.h>
53: #include <sys/sockio.h>
54: #include <sys/sysctl.h>
1.17 elad 55: #include <sys/kauth.h>
1.34 ad 56: #include <sys/mutex.h>
1.37 ad 57: #include <sys/simplelock.h>
1.42 ad 58: #include <sys/intr.h>
1.1 cube 59:
60: #include <net/if.h>
61: #include <net/if_dl.h>
62: #include <net/if_ether.h>
63: #include <net/if_media.h>
64: #include <net/if_tap.h>
65: #if NBPFILTER > 0
66: #include <net/bpf.h>
67: #endif
68:
1.29 christos 69: #include <compat/sys/sockio.h>
70:
1.1 cube 71: /*
72: * sysctl node management
73: *
74: * It's not really possible to use a SYSCTL_SETUP block with
75: * current LKM implementation, so it is easier to just define
76: * our own function.
77: *
78: * The handler function is a "helper" in Andrew Brown's sysctl
79: * framework terminology. It is used as a gateway for sysctl
80: * requests over the nodes.
81: *
82: * tap_log allows the module to log creations of nodes and
83: * destroy them all at once using sysctl_teardown.
84: */
85: static int tap_node;
86: static int tap_sysctl_handler(SYSCTLFN_PROTO);
1.2 cube 87: SYSCTL_SETUP_PROTO(sysctl_tap_setup);
1.1 cube 88:
89: /*
90: * Since we're an Ethernet device, we need the 3 following
91: * components: a leading struct device, a struct ethercom,
92: * and also a struct ifmedia since we don't attach a PHY to
93: * ourselves. We could emulate one, but there's no real
94: * point.
95: */
96:
97: struct tap_softc {
1.40 cube 98: device_t sc_dev;
1.1 cube 99: struct ifmedia sc_im;
100: struct ethercom sc_ec;
101: int sc_flags;
102: #define TAP_INUSE 0x00000001 /* tap device can only be opened once */
103: #define TAP_ASYNCIO 0x00000002 /* user is using async I/O (SIGIO) on the device */
104: #define TAP_NBIO 0x00000004 /* user wants calls to avoid blocking */
105: #define TAP_GOING 0x00000008 /* interface is being destroyed */
106: struct selinfo sc_rsel;
107: pid_t sc_pgid; /* For async. IO */
1.34 ad 108: kmutex_t sc_rdlock;
1.1 cube 109: struct simplelock sc_kqlock;
1.42 ad 110: void *sc_sih;
1.1 cube 111: };
112:
113: /* autoconf(9) glue */
114:
115: void tapattach(int);
116:
1.40 cube 117: static int tap_match(device_t, cfdata_t, void *);
118: static void tap_attach(device_t, device_t, void *);
119: static int tap_detach(device_t, int);
1.1 cube 120:
1.40 cube 121: CFATTACH_DECL_NEW(tap, sizeof(struct tap_softc),
1.1 cube 122: tap_match, tap_attach, tap_detach, NULL);
123: extern struct cfdriver tap_cd;
124:
125: /* Real device access routines */
126: static int tap_dev_close(struct tap_softc *);
127: static int tap_dev_read(int, struct uio *, int);
128: static int tap_dev_write(int, struct uio *, int);
1.26 christos 129: static int tap_dev_ioctl(int, u_long, void *, struct lwp *);
1.11 christos 130: static int tap_dev_poll(int, int, struct lwp *);
1.1 cube 131: static int tap_dev_kqfilter(int, struct knote *);
132:
133: /* Fileops access routines */
1.41 ad 134: static int tap_fops_close(file_t *);
135: static int tap_fops_read(file_t *, off_t *, struct uio *,
1.17 elad 136: kauth_cred_t, int);
1.41 ad 137: static int tap_fops_write(file_t *, off_t *, struct uio *,
1.17 elad 138: kauth_cred_t, int);
1.41 ad 139: static int tap_fops_ioctl(file_t *, u_long, void *);
140: static int tap_fops_poll(file_t *, int);
141: static int tap_fops_kqfilter(file_t *, struct knote *);
1.1 cube 142:
143: static const struct fileops tap_fileops = {
144: tap_fops_read,
145: tap_fops_write,
146: tap_fops_ioctl,
147: fnullop_fcntl,
148: tap_fops_poll,
149: fbadop_stat,
150: tap_fops_close,
151: tap_fops_kqfilter,
152: };
153:
154: /* Helper for cloning open() */
1.11 christos 155: static int tap_dev_cloner(struct lwp *);
1.1 cube 156:
157: /* Character device routines */
1.11 christos 158: static int tap_cdev_open(dev_t, int, int, struct lwp *);
159: static int tap_cdev_close(dev_t, int, int, struct lwp *);
1.1 cube 160: static int tap_cdev_read(dev_t, struct uio *, int);
161: static int tap_cdev_write(dev_t, struct uio *, int);
1.26 christos 162: static int tap_cdev_ioctl(dev_t, u_long, void *, int, struct lwp *);
1.11 christos 163: static int tap_cdev_poll(dev_t, int, struct lwp *);
1.1 cube 164: static int tap_cdev_kqfilter(dev_t, struct knote *);
165:
166: const struct cdevsw tap_cdevsw = {
167: tap_cdev_open, tap_cdev_close,
168: tap_cdev_read, tap_cdev_write,
169: tap_cdev_ioctl, nostop, notty,
170: tap_cdev_poll, nommap,
171: tap_cdev_kqfilter,
1.20 christos 172: D_OTHER,
1.1 cube 173: };
174:
175: #define TAP_CLONER 0xfffff /* Maximal minor value */
176:
177: /* kqueue-related routines */
178: static void tap_kqdetach(struct knote *);
179: static int tap_kqread(struct knote *, long);
180:
181: /*
182: * Those are needed by the if_media interface.
183: */
184:
185: static int tap_mediachange(struct ifnet *);
186: static void tap_mediastatus(struct ifnet *, struct ifmediareq *);
187:
188: /*
189: * Those are needed by the ifnet interface, and would typically be
190: * there for any network interface driver.
191: * Some other routines are optional: watchdog and drain.
192: */
193:
194: static void tap_start(struct ifnet *);
195: static void tap_stop(struct ifnet *, int);
196: static int tap_init(struct ifnet *);
1.26 christos 197: static int tap_ioctl(struct ifnet *, u_long, void *);
1.1 cube 198:
1.42 ad 199: /* Internal functions */
1.1 cube 200: static int tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *);
1.42 ad 201: static void tap_softintr(void *);
1.1 cube 202:
203: /*
204: * tap is a clonable interface, although it is highly unrealistic for
205: * an Ethernet device.
206: *
207: * Here are the bits needed for a clonable interface.
208: */
209: static int tap_clone_create(struct if_clone *, int);
210: static int tap_clone_destroy(struct ifnet *);
211:
212: struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap",
213: tap_clone_create,
214: tap_clone_destroy);
215:
216: /* Helper functionis shared by the two cloning code paths */
217: static struct tap_softc * tap_clone_creator(int);
1.40 cube 218: int tap_clone_destroyer(device_t);
1.1 cube 219:
220: void
1.23 christos 221: tapattach(int n)
1.1 cube 222: {
223: int error;
224:
225: error = config_cfattach_attach(tap_cd.cd_name, &tap_ca);
226: if (error) {
227: aprint_error("%s: unable to register cfattach\n",
228: tap_cd.cd_name);
229: (void)config_cfdriver_detach(&tap_cd);
230: return;
231: }
232:
233: if_clone_attach(&tap_cloners);
234: }
235:
236: /* Pretty much useless for a pseudo-device */
237: static int
1.40 cube 238: tap_match(device_t parent, cfdata_t cfdata, void *arg)
1.1 cube 239: {
1.40 cube 240:
1.1 cube 241: return (1);
242: }
243:
244: void
1.40 cube 245: tap_attach(device_t parent, device_t self, void *aux)
1.1 cube 246: {
1.40 cube 247: struct tap_softc *sc = device_private(self);
1.1 cube 248: struct ifnet *ifp;
1.18 kardel 249: const struct sysctlnode *node;
1.38 matt 250: uint8_t enaddr[ETHER_ADDR_LEN] =
1.7 cube 251: { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
1.14 christos 252: char enaddrstr[3 * ETHER_ADDR_LEN];
1.18 kardel 253: struct timeval tv;
1.1 cube 254: uint32_t ui;
255: int error;
256:
1.40 cube 257: sc->sc_dev = self;
1.42 ad 258: sc->sc_sih = softint_establish(SOFTINT_CLOCK, tap_softintr, sc);
1.40 cube 259:
1.47.4.1 snj 260: if (!pmf_device_register(self, NULL, NULL))
261: aprint_error_dev(self, "couldn't establish power handler\n");
262:
1.1 cube 263: /*
264: * In order to obtain unique initial Ethernet address on a host,
1.18 kardel 265: * do some randomisation using the current uptime. It's not meant
266: * for anything but avoiding hard-coding an address.
1.1 cube 267: */
1.18 kardel 268: getmicrouptime(&tv);
269: ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
1.38 matt 270: memcpy(enaddr+3, (uint8_t *)&ui, 3);
1.1 cube 271:
1.40 cube 272: aprint_verbose_dev(self, "Ethernet address %s\n",
1.14 christos 273: ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr));
1.1 cube 274:
275: /*
276: * Why 1000baseT? Why not? You can add more.
277: *
278: * Note that there are 3 steps: init, one or several additions to
279: * list of supported media, and in the end, the selection of one
280: * of them.
281: */
282: ifmedia_init(&sc->sc_im, 0, tap_mediachange, tap_mediastatus);
283: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_1000_T, 0, NULL);
284: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
285: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_100_TX, 0, NULL);
286: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
287: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_10_T, 0, NULL);
288: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
289: ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_AUTO, 0, NULL);
290: ifmedia_set(&sc->sc_im, IFM_ETHER|IFM_AUTO);
291:
292: /*
293: * One should note that an interface must do multicast in order
294: * to support IPv6.
295: */
296: ifp = &sc->sc_ec.ec_if;
1.40 cube 297: strcpy(ifp->if_xname, device_xname(self));
1.1 cube 298: ifp->if_softc = sc;
299: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
300: ifp->if_ioctl = tap_ioctl;
301: ifp->if_start = tap_start;
302: ifp->if_stop = tap_stop;
303: ifp->if_init = tap_init;
304: IFQ_SET_READY(&ifp->if_snd);
305:
306: sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
307:
308: /* Those steps are mandatory for an Ethernet driver, the fisrt call
309: * being common to all network interface drivers. */
310: if_attach(ifp);
311: ether_ifattach(ifp, enaddr);
312:
313: sc->sc_flags = 0;
314:
315: /*
316: * Add a sysctl node for that interface.
317: *
318: * The pointer transmitted is not a string, but instead a pointer to
319: * the softc structure, which we can use to build the string value on
320: * the fly in the helper function of the node. See the comments for
321: * tap_sysctl_handler for details.
1.21 cube 322: *
323: * Usually sysctl_createv is called with CTL_CREATE as the before-last
324: * component. However, we can allocate a number ourselves, as we are
325: * the only consumer of the net.link.<iface> node. In this case, the
326: * unit number is conveniently used to number the node. CTL_CREATE
327: * would just work, too.
1.1 cube 328: */
329: if ((error = sysctl_createv(NULL, 0, NULL,
330: &node, CTLFLAG_READWRITE,
1.40 cube 331: CTLTYPE_STRING, device_xname(self), NULL,
1.1 cube 332: tap_sysctl_handler, 0, sc, 18,
1.40 cube 333: CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev),
1.15 thorpej 334: CTL_EOL)) != 0)
1.40 cube 335: aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n",
336: error);
1.1 cube 337:
338: /*
339: * Initialize the two locks for the device.
340: *
341: * We need a lock here because even though the tap device can be
342: * opened only once, the file descriptor might be passed to another
343: * process, say a fork(2)ed child.
344: *
345: * The Giant saves us from most of the hassle, but since the read
346: * operation can sleep, we don't want two processes to wake up at
347: * the same moment and both try and dequeue a single packet.
348: *
349: * The queue for event listeners (used by kqueue(9), see below) has
350: * to be protected, too, but we don't need the same level of
351: * complexity for that lock, so a simple spinning lock is fine.
352: */
1.34 ad 353: mutex_init(&sc->sc_rdlock, MUTEX_DEFAULT, IPL_NONE);
1.1 cube 354: simple_lock_init(&sc->sc_kqlock);
1.47 rmind 355:
356: selinit(&sc->sc_rsel);
1.1 cube 357: }
358:
359: /*
360: * When detaching, we do the inverse of what is done in the attach
361: * routine, in reversed order.
362: */
363: static int
1.40 cube 364: tap_detach(device_t self, int flags)
1.1 cube 365: {
1.40 cube 366: struct tap_softc *sc = device_private(self);
1.1 cube 367: struct ifnet *ifp = &sc->sc_ec.ec_if;
368: int error, s;
369:
370: sc->sc_flags |= TAP_GOING;
371: s = splnet();
372: tap_stop(ifp, 1);
373: if_down(ifp);
374: splx(s);
375:
1.42 ad 376: softint_disestablish(sc->sc_sih);
377:
1.1 cube 378: /*
379: * Destroying a single leaf is a very straightforward operation using
380: * sysctl_destroyv. One should be sure to always end the path with
381: * CTL_EOL.
382: */
1.3 cube 383: if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node,
1.40 cube 384: device_unit(sc->sc_dev), CTL_EOL)) != 0)
385: aprint_error_dev(self,
386: "sysctl_destroyv returned %d, ignoring\n", error);
1.1 cube 387: ether_ifdetach(ifp);
388: if_detach(ifp);
389: ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY);
1.47 rmind 390: seldestroy(&sc->sc_rsel);
1.34 ad 391: mutex_destroy(&sc->sc_rdlock);
1.1 cube 392:
1.47.4.2 snj 393: pmf_device_deregister(self);
394:
1.1 cube 395: return (0);
396: }
397:
398: /*
399: * This function is called by the ifmedia layer to notify the driver
400: * that the user requested a media change. A real driver would
401: * reconfigure the hardware.
402: */
403: static int
1.23 christos 404: tap_mediachange(struct ifnet *ifp)
1.1 cube 405: {
406: return (0);
407: }
408:
409: /*
410: * Here the user asks for the currently used media.
411: */
412: static void
413: tap_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
414: {
415: struct tap_softc *sc = (struct tap_softc *)ifp->if_softc;
416: imr->ifm_active = sc->sc_im.ifm_cur->ifm_media;
417: }
418:
419: /*
420: * This is the function where we SEND packets.
421: *
422: * There is no 'receive' equivalent. A typical driver will get
423: * interrupts from the hardware, and from there will inject new packets
424: * into the network stack.
425: *
426: * Once handled, a packet must be freed. A real driver might not be able
427: * to fit all the pending packets into the hardware, and is allowed to
428: * return before having sent all the packets. It should then use the
429: * if_flags flag IFF_OACTIVE to notify the upper layer.
430: *
431: * There are also other flags one should check, such as IFF_PAUSE.
432: *
433: * It is our duty to make packets available to BPF listeners.
434: *
435: * You should be aware that this function is called by the Ethernet layer
436: * at splnet().
437: *
438: * When the device is opened, we have to pass the packet(s) to the
439: * userland. For that we stay in OACTIVE mode while the userland gets
440: * the packets, and we send a signal to the processes waiting to read.
441: *
442: * wakeup(sc) is the counterpart to the tsleep call in
443: * tap_dev_read, while selnotify() is used for kevent(2) and
444: * poll(2) (which includes select(2)) listeners.
445: */
446: static void
447: tap_start(struct ifnet *ifp)
448: {
449: struct tap_softc *sc = (struct tap_softc *)ifp->if_softc;
450: struct mbuf *m0;
451:
452: if ((sc->sc_flags & TAP_INUSE) == 0) {
453: /* Simply drop packets */
454: for(;;) {
455: IFQ_DEQUEUE(&ifp->if_snd, m0);
456: if (m0 == NULL)
457: return;
458:
459: ifp->if_opackets++;
460: #if NBPFILTER > 0
461: if (ifp->if_bpf)
462: bpf_mtap(ifp->if_bpf, m0);
463: #endif
464:
465: m_freem(m0);
466: }
467: } else if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
468: ifp->if_flags |= IFF_OACTIVE;
469: wakeup(sc);
1.39 rmind 470: selnotify(&sc->sc_rsel, 0, 1);
1.1 cube 471: if (sc->sc_flags & TAP_ASYNCIO)
1.42 ad 472: softint_schedule(sc->sc_sih);
473: }
474: }
475:
476: static void
477: tap_softintr(void *cookie)
478: {
479: struct tap_softc *sc;
480: struct ifnet *ifp;
481: int a, b;
482:
483: sc = cookie;
484:
485: if (sc->sc_flags & TAP_ASYNCIO) {
486: ifp = &sc->sc_ec.ec_if;
487: if (ifp->if_flags & IFF_RUNNING) {
488: a = POLL_IN;
489: b = POLLIN|POLLRDNORM;
490: } else {
491: a = POLL_HUP;
492: b = 0;
493: }
494: fownsignal(sc->sc_pgid, SIGIO, a, b, NULL);
1.1 cube 495: }
496: }
497:
498: /*
499: * A typical driver will only contain the following handlers for
500: * ioctl calls, except SIOCSIFPHYADDR.
501: * The latter is a hack I used to set the Ethernet address of the
502: * faked device.
503: *
504: * Note that both ifmedia_ioctl() and ether_ioctl() have to be
505: * called under splnet().
506: */
507: static int
1.26 christos 508: tap_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1.1 cube 509: {
510: struct tap_softc *sc = (struct tap_softc *)ifp->if_softc;
511: struct ifreq *ifr = (struct ifreq *)data;
512: int s, error;
513:
514: s = splnet();
515:
516: switch (cmd) {
1.29 christos 517: #ifdef OSIOCSIFMEDIA
518: case OSIOCSIFMEDIA:
519: #endif
1.1 cube 520: case SIOCSIFMEDIA:
521: case SIOCGIFMEDIA:
522: error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd);
523: break;
524: case SIOCSIFPHYADDR:
525: error = tap_lifaddr(ifp, cmd, (struct ifaliasreq *)data);
526: break;
527: default:
528: error = ether_ioctl(ifp, cmd, data);
529: if (error == ENETRESET)
530: error = 0;
531: break;
532: }
533:
534: splx(s);
535:
536: return (error);
537: }
538:
539: /*
540: * Helper function to set Ethernet address. This shouldn't be done there,
541: * and should actually be available to all Ethernet drivers, real or not.
542: */
543: static int
1.23 christos 544: tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra)
1.1 cube 545: {
1.36 dyoung 546: const struct sockaddr_dl *sdl = satosdl(&ifra->ifra_addr);
1.1 cube 547:
1.36 dyoung 548: if (sdl->sdl_family != AF_LINK)
1.1 cube 549: return (EINVAL);
550:
1.36 dyoung 551: if_set_sadl(ifp, CLLADDR(sdl), ETHER_ADDR_LEN);
1.1 cube 552:
553: return (0);
554: }
555:
556: /*
557: * _init() would typically be called when an interface goes up,
558: * meaning it should configure itself into the state in which it
559: * can send packets.
560: */
561: static int
562: tap_init(struct ifnet *ifp)
563: {
564: ifp->if_flags |= IFF_RUNNING;
565:
566: tap_start(ifp);
567:
568: return (0);
569: }
570:
571: /*
572: * _stop() is called when an interface goes down. It is our
573: * responsability to validate that state by clearing the
574: * IFF_RUNNING flag.
575: *
576: * We have to wake up all the sleeping processes to have the pending
577: * read requests cancelled.
578: */
579: static void
1.23 christos 580: tap_stop(struct ifnet *ifp, int disable)
1.1 cube 581: {
582: struct tap_softc *sc = (struct tap_softc *)ifp->if_softc;
583:
584: ifp->if_flags &= ~IFF_RUNNING;
585: wakeup(sc);
1.39 rmind 586: selnotify(&sc->sc_rsel, 0, 1);
1.1 cube 587: if (sc->sc_flags & TAP_ASYNCIO)
1.42 ad 588: softint_schedule(sc->sc_sih);
1.1 cube 589: }
590:
591: /*
592: * The 'create' command of ifconfig can be used to create
593: * any numbered instance of a given device. Thus we have to
594: * make sure we have enough room in cd_devs to create the
595: * user-specified instance. config_attach_pseudo will do this
596: * for us.
597: */
598: static int
1.23 christos 599: tap_clone_create(struct if_clone *ifc, int unit)
1.1 cube 600: {
601: if (tap_clone_creator(unit) == NULL) {
602: aprint_error("%s%d: unable to attach an instance\n",
603: tap_cd.cd_name, unit);
604: return (ENXIO);
605: }
606:
607: return (0);
608: }
609:
610: /*
611: * tap(4) can be cloned by two ways:
612: * using 'ifconfig tap0 create', which will use the network
613: * interface cloning API, and call tap_clone_create above.
614: * opening the cloning device node, whose minor number is TAP_CLONER.
615: * See below for an explanation on how this part work.
616: */
617: static struct tap_softc *
618: tap_clone_creator(int unit)
619: {
620: struct cfdata *cf;
621:
622: cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
623: cf->cf_name = tap_cd.cd_name;
624: cf->cf_atname = tap_ca.ca_name;
1.27 drochner 625: if (unit == -1) {
626: /* let autoconf find the first free one */
627: cf->cf_unit = 0;
628: cf->cf_fstate = FSTATE_STAR;
629: } else {
630: cf->cf_unit = unit;
1.45 dyoung 631: cf->cf_fstate = FSTATE_FOUND;
1.27 drochner 632: }
1.1 cube 633:
1.40 cube 634: return device_private(config_attach_pseudo(cf));
1.1 cube 635: }
636:
637: /*
638: * The clean design of if_clone and autoconf(9) makes that part
639: * really straightforward. The second argument of config_detach
640: * means neither QUIET nor FORCED.
641: */
642: static int
643: tap_clone_destroy(struct ifnet *ifp)
644: {
1.45 dyoung 645: struct tap_softc *sc = ifp->if_softc;
646:
647: return tap_clone_destroyer(sc->sc_dev);
1.1 cube 648: }
649:
1.12 cube 650: int
1.40 cube 651: tap_clone_destroyer(device_t dev)
1.1 cube 652: {
1.40 cube 653: cfdata_t cf = device_cfdata(dev);
1.1 cube 654: int error;
655:
656: if ((error = config_detach(dev, 0)) != 0)
1.40 cube 657: aprint_error_dev(dev, "unable to detach instance\n");
1.1 cube 658: free(cf, M_DEVBUF);
659:
660: return (error);
661: }
662:
663: /*
664: * tap(4) is a bit of an hybrid device. It can be used in two different
665: * ways:
666: * 1. ifconfig tapN create, then use /dev/tapN to read/write off it.
667: * 2. open /dev/tap, get a new interface created and read/write off it.
668: * That interface is destroyed when the process that had it created exits.
669: *
670: * The first way is managed by the cdevsw structure, and you access interfaces
671: * through a (major, minor) mapping: tap4 is obtained by the minor number
672: * 4. The entry points for the cdevsw interface are prefixed by tap_cdev_.
673: *
674: * The second way is the so-called "cloning" device. It's a special minor
675: * number (chosen as the maximal number, to allow as much tap devices as
676: * possible). The user first opens the cloner (e.g., /dev/tap), and that
677: * call ends in tap_cdev_open. The actual place where it is handled is
678: * tap_dev_cloner.
679: *
680: * An tap device cannot be opened more than once at a time, so the cdevsw
681: * part of open() does nothing but noting that the interface is being used and
682: * hence ready to actually handle packets.
683: */
684:
685: static int
1.23 christos 686: tap_cdev_open(dev_t dev, int flags, int fmt, struct lwp *l)
1.1 cube 687: {
688: struct tap_softc *sc;
689:
690: if (minor(dev) == TAP_CLONER)
1.11 christos 691: return tap_dev_cloner(l);
1.1 cube 692:
1.46 cegger 693: sc = device_lookup_private(&tap_cd, minor(dev));
1.1 cube 694: if (sc == NULL)
695: return (ENXIO);
696:
697: /* The device can only be opened once */
698: if (sc->sc_flags & TAP_INUSE)
699: return (EBUSY);
700: sc->sc_flags |= TAP_INUSE;
701: return (0);
702: }
703:
704: /*
705: * There are several kinds of cloning devices, and the most simple is the one
706: * tap(4) uses. What it does is change the file descriptor with a new one,
707: * with its own fileops structure (which maps to the various read, write,
708: * ioctl functions). It starts allocating a new file descriptor with falloc,
709: * then actually creates the new tap devices.
710: *
711: * Once those two steps are successful, we can re-wire the existing file
712: * descriptor to its new self. This is done with fdclone(): it fills the fp
713: * structure as needed (notably f_data gets filled with the fifth parameter
714: * passed, the unit of the tap device which will allows us identifying the
715: * device later), and returns EMOVEFD.
716: *
717: * That magic value is interpreted by sys_open() which then replaces the
718: * current file descriptor by the new one (through a magic member of struct
1.13 pooka 719: * lwp, l_dupfd).
1.1 cube 720: *
721: * The tap device is flagged as being busy since it otherwise could be
722: * externally accessed through the corresponding device node with the cdevsw
723: * interface.
724: */
725:
726: static int
1.11 christos 727: tap_dev_cloner(struct lwp *l)
1.1 cube 728: {
729: struct tap_softc *sc;
1.41 ad 730: file_t *fp;
1.1 cube 731: int error, fd;
732:
1.41 ad 733: if ((error = fd_allocfile(&fp, &fd)) != 0)
1.1 cube 734: return (error);
735:
1.27 drochner 736: if ((sc = tap_clone_creator(-1)) == NULL) {
1.41 ad 737: fd_abort(curproc, fp, fd);
1.1 cube 738: return (ENXIO);
739: }
740:
741: sc->sc_flags |= TAP_INUSE;
742:
1.41 ad 743: return fd_clone(fp, fd, FREAD|FWRITE, &tap_fileops,
1.40 cube 744: (void *)(intptr_t)device_unit(sc->sc_dev));
1.1 cube 745: }
746:
747: /*
748: * While all other operations (read, write, ioctl, poll and kqfilter) are
749: * really the same whether we are in cdevsw or fileops mode, the close()
750: * function is slightly different in the two cases.
751: *
752: * As for the other, the core of it is shared in tap_dev_close. What
753: * it does is sufficient for the cdevsw interface, but the cloning interface
754: * needs another thing: the interface is destroyed when the processes that
755: * created it closes it.
756: */
757: static int
1.23 christos 758: tap_cdev_close(dev_t dev, int flags, int fmt,
759: struct lwp *l)
1.1 cube 760: {
761: struct tap_softc *sc =
1.46 cegger 762: device_lookup_private(&tap_cd, minor(dev));
1.1 cube 763:
764: if (sc == NULL)
765: return (ENXIO);
766:
767: return tap_dev_close(sc);
768: }
769:
770: /*
771: * It might happen that the administrator used ifconfig to externally destroy
772: * the interface. In that case, tap_fops_close will be called while
773: * tap_detach is already happening. If we called it again from here, we
774: * would dead lock. TAP_GOING ensures that this situation doesn't happen.
775: */
776: static int
1.41 ad 777: tap_fops_close(file_t *fp)
1.1 cube 778: {
779: int unit = (intptr_t)fp->f_data;
780: struct tap_softc *sc;
781: int error;
782:
1.46 cegger 783: sc = device_lookup_private(&tap_cd, unit);
1.1 cube 784: if (sc == NULL)
785: return (ENXIO);
786:
787: /* tap_dev_close currently always succeeds, but it might not
788: * always be the case. */
1.44 ad 789: KERNEL_LOCK(1, NULL);
790: if ((error = tap_dev_close(sc)) != 0) {
791: KERNEL_UNLOCK_ONE(NULL);
1.1 cube 792: return (error);
1.44 ad 793: }
1.1 cube 794:
795: /* Destroy the device now that it is no longer useful,
796: * unless it's already being destroyed. */
1.44 ad 797: if ((sc->sc_flags & TAP_GOING) != 0) {
798: KERNEL_UNLOCK_ONE(NULL);
1.1 cube 799: return (0);
1.44 ad 800: }
1.1 cube 801:
1.44 ad 802: error = tap_clone_destroyer(sc->sc_dev);
803: KERNEL_UNLOCK_ONE(NULL);
804: return error;
1.1 cube 805: }
806:
807: static int
808: tap_dev_close(struct tap_softc *sc)
809: {
810: struct ifnet *ifp;
811: int s;
812:
813: s = splnet();
814: /* Let tap_start handle packets again */
815: ifp = &sc->sc_ec.ec_if;
816: ifp->if_flags &= ~IFF_OACTIVE;
817:
818: /* Purge output queue */
819: if (!(IFQ_IS_EMPTY(&ifp->if_snd))) {
820: struct mbuf *m;
821:
822: for (;;) {
823: IFQ_DEQUEUE(&ifp->if_snd, m);
824: if (m == NULL)
825: break;
826:
827: ifp->if_opackets++;
828: #if NBPFILTER > 0
829: if (ifp->if_bpf)
830: bpf_mtap(ifp->if_bpf, m);
831: #endif
832: }
833: }
834: splx(s);
835:
836: sc->sc_flags &= ~(TAP_INUSE | TAP_ASYNCIO);
837:
838: return (0);
839: }
840:
841: static int
842: tap_cdev_read(dev_t dev, struct uio *uio, int flags)
843: {
844: return tap_dev_read(minor(dev), uio, flags);
845: }
846:
847: static int
1.41 ad 848: tap_fops_read(file_t *fp, off_t *offp, struct uio *uio,
1.23 christos 849: kauth_cred_t cred, int flags)
1.1 cube 850: {
1.44 ad 851: int error;
852:
853: KERNEL_LOCK(1, NULL);
854: error = tap_dev_read((intptr_t)fp->f_data, uio, flags);
855: KERNEL_UNLOCK_ONE(NULL);
856: return error;
1.1 cube 857: }
858:
859: static int
1.23 christos 860: tap_dev_read(int unit, struct uio *uio, int flags)
1.1 cube 861: {
862: struct tap_softc *sc =
1.46 cegger 863: device_lookup_private(&tap_cd, unit);
1.1 cube 864: struct ifnet *ifp;
865: struct mbuf *m, *n;
866: int error = 0, s;
867:
868: if (sc == NULL)
869: return (ENXIO);
870:
871: ifp = &sc->sc_ec.ec_if;
872: if ((ifp->if_flags & IFF_UP) == 0)
873: return (EHOSTDOWN);
874:
875: /*
876: * In the TAP_NBIO case, we have to make sure we won't be sleeping
877: */
1.34 ad 878: if ((sc->sc_flags & TAP_NBIO) != 0) {
879: if (!mutex_tryenter(&sc->sc_rdlock))
880: return (EWOULDBLOCK);
881: } else {
882: mutex_enter(&sc->sc_rdlock);
883: }
1.1 cube 884:
885: s = splnet();
886: if (IFQ_IS_EMPTY(&ifp->if_snd)) {
887: ifp->if_flags &= ~IFF_OACTIVE;
888: /*
889: * We must release the lock before sleeping, and re-acquire it
890: * after.
891: */
1.34 ad 892: mutex_exit(&sc->sc_rdlock);
1.1 cube 893: if (sc->sc_flags & TAP_NBIO)
894: error = EWOULDBLOCK;
895: else
896: error = tsleep(sc, PSOCK|PCATCH, "tap", 0);
1.47.4.3! snj 897: splx(s);
! 898:
1.1 cube 899: if (error != 0)
900: return (error);
901: /* The device might have been downed */
902: if ((ifp->if_flags & IFF_UP) == 0)
903: return (EHOSTDOWN);
1.34 ad 904: if ((sc->sc_flags & TAP_NBIO)) {
905: if (!mutex_tryenter(&sc->sc_rdlock))
906: return (EWOULDBLOCK);
907: } else {
908: mutex_enter(&sc->sc_rdlock);
909: }
1.1 cube 910: s = splnet();
911: }
912:
913: IFQ_DEQUEUE(&ifp->if_snd, m);
914: ifp->if_flags &= ~IFF_OACTIVE;
915: splx(s);
916: if (m == NULL) {
917: error = 0;
918: goto out;
919: }
920:
921: ifp->if_opackets++;
922: #if NBPFILTER > 0
923: if (ifp->if_bpf)
924: bpf_mtap(ifp->if_bpf, m);
925: #endif
926:
927: /*
928: * One read is one packet.
929: */
930: do {
1.26 christos 931: error = uiomove(mtod(m, void *),
1.1 cube 932: min(m->m_len, uio->uio_resid), uio);
933: MFREE(m, n);
934: m = n;
935: } while (m != NULL && uio->uio_resid > 0 && error == 0);
936:
937: if (m != NULL)
938: m_freem(m);
939:
940: out:
1.34 ad 941: mutex_exit(&sc->sc_rdlock);
1.1 cube 942: return (error);
943: }
944:
945: static int
946: tap_cdev_write(dev_t dev, struct uio *uio, int flags)
947: {
948: return tap_dev_write(minor(dev), uio, flags);
949: }
950:
951: static int
1.41 ad 952: tap_fops_write(file_t *fp, off_t *offp, struct uio *uio,
1.23 christos 953: kauth_cred_t cred, int flags)
1.1 cube 954: {
1.44 ad 955: int error;
956:
957: KERNEL_LOCK(1, NULL);
958: error = tap_dev_write((intptr_t)fp->f_data, uio, flags);
959: KERNEL_UNLOCK_ONE(NULL);
960: return error;
1.1 cube 961: }
962:
963: static int
1.23 christos 964: tap_dev_write(int unit, struct uio *uio, int flags)
1.1 cube 965: {
966: struct tap_softc *sc =
1.46 cegger 967: device_lookup_private(&tap_cd, unit);
1.1 cube 968: struct ifnet *ifp;
969: struct mbuf *m, **mp;
970: int error = 0;
1.9 bouyer 971: int s;
1.1 cube 972:
973: if (sc == NULL)
974: return (ENXIO);
975:
976: ifp = &sc->sc_ec.ec_if;
977:
978: /* One write, one packet, that's the rule */
979: MGETHDR(m, M_DONTWAIT, MT_DATA);
980: if (m == NULL) {
981: ifp->if_ierrors++;
982: return (ENOBUFS);
983: }
984: m->m_pkthdr.len = uio->uio_resid;
985:
986: mp = &m;
987: while (error == 0 && uio->uio_resid > 0) {
988: if (*mp != m) {
989: MGET(*mp, M_DONTWAIT, MT_DATA);
990: if (*mp == NULL) {
991: error = ENOBUFS;
992: break;
993: }
994: }
995: (*mp)->m_len = min(MHLEN, uio->uio_resid);
1.26 christos 996: error = uiomove(mtod(*mp, void *), (*mp)->m_len, uio);
1.1 cube 997: mp = &(*mp)->m_next;
998: }
999: if (error) {
1000: ifp->if_ierrors++;
1001: m_freem(m);
1002: return (error);
1003: }
1004:
1005: ifp->if_ipackets++;
1006: m->m_pkthdr.rcvif = ifp;
1007:
1008: #if NBPFILTER > 0
1009: if (ifp->if_bpf)
1010: bpf_mtap(ifp->if_bpf, m);
1011: #endif
1.9 bouyer 1012: s =splnet();
1.1 cube 1013: (*ifp->if_input)(ifp, m);
1.9 bouyer 1014: splx(s);
1.1 cube 1015:
1016: return (0);
1017: }
1018:
1019: static int
1.26 christos 1020: tap_cdev_ioctl(dev_t dev, u_long cmd, void *data, int flags,
1.11 christos 1021: struct lwp *l)
1.1 cube 1022: {
1.11 christos 1023: return tap_dev_ioctl(minor(dev), cmd, data, l);
1.1 cube 1024: }
1025:
1026: static int
1.41 ad 1027: tap_fops_ioctl(file_t *fp, u_long cmd, void *data)
1.1 cube 1028: {
1.41 ad 1029: return tap_dev_ioctl((intptr_t)fp->f_data, cmd, data, curlwp);
1.1 cube 1030: }
1031:
1032: static int
1.26 christos 1033: tap_dev_ioctl(int unit, u_long cmd, void *data, struct lwp *l)
1.1 cube 1034: {
1035: struct tap_softc *sc =
1.46 cegger 1036: device_lookup_private(&tap_cd, unit);
1.1 cube 1037: int error = 0;
1038:
1039: if (sc == NULL)
1040: return (ENXIO);
1041:
1042: switch (cmd) {
1043: case FIONREAD:
1044: {
1045: struct ifnet *ifp = &sc->sc_ec.ec_if;
1046: struct mbuf *m;
1047: int s;
1048:
1049: s = splnet();
1050: IFQ_POLL(&ifp->if_snd, m);
1051:
1052: if (m == NULL)
1053: *(int *)data = 0;
1054: else
1055: *(int *)data = m->m_pkthdr.len;
1056: splx(s);
1057: } break;
1058: case TIOCSPGRP:
1059: case FIOSETOWN:
1.41 ad 1060: error = fsetown(&sc->sc_pgid, cmd, data);
1.1 cube 1061: break;
1062: case TIOCGPGRP:
1063: case FIOGETOWN:
1.41 ad 1064: error = fgetown(sc->sc_pgid, cmd, data);
1.1 cube 1065: break;
1066: case FIOASYNC:
1067: if (*(int *)data)
1068: sc->sc_flags |= TAP_ASYNCIO;
1069: else
1070: sc->sc_flags &= ~TAP_ASYNCIO;
1071: break;
1072: case FIONBIO:
1073: if (*(int *)data)
1074: sc->sc_flags |= TAP_NBIO;
1075: else
1076: sc->sc_flags &= ~TAP_NBIO;
1077: break;
1.29 christos 1078: #ifdef OTAPGIFNAME
1079: case OTAPGIFNAME:
1080: #endif
1.1 cube 1081: case TAPGIFNAME:
1082: {
1083: struct ifreq *ifr = (struct ifreq *)data;
1084: struct ifnet *ifp = &sc->sc_ec.ec_if;
1085:
1086: strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
1087: } break;
1088: default:
1089: error = ENOTTY;
1090: break;
1091: }
1092:
1093: return (0);
1094: }
1095:
1096: static int
1.11 christos 1097: tap_cdev_poll(dev_t dev, int events, struct lwp *l)
1.1 cube 1098: {
1.11 christos 1099: return tap_dev_poll(minor(dev), events, l);
1.1 cube 1100: }
1101:
1102: static int
1.41 ad 1103: tap_fops_poll(file_t *fp, int events)
1.1 cube 1104: {
1.41 ad 1105: return tap_dev_poll((intptr_t)fp->f_data, events, curlwp);
1.1 cube 1106: }
1107:
1108: static int
1.11 christos 1109: tap_dev_poll(int unit, int events, struct lwp *l)
1.1 cube 1110: {
1111: struct tap_softc *sc =
1.46 cegger 1112: device_lookup_private(&tap_cd, unit);
1.1 cube 1113: int revents = 0;
1114:
1115: if (sc == NULL)
1.28 christos 1116: return POLLERR;
1.1 cube 1117:
1118: if (events & (POLLIN|POLLRDNORM)) {
1119: struct ifnet *ifp = &sc->sc_ec.ec_if;
1120: struct mbuf *m;
1121: int s;
1122:
1123: s = splnet();
1124: IFQ_POLL(&ifp->if_snd, m);
1125: splx(s);
1126:
1127: if (m != NULL)
1128: revents |= events & (POLLIN|POLLRDNORM);
1129: else {
1.4 ragge 1130: simple_lock(&sc->sc_kqlock);
1.11 christos 1131: selrecord(l, &sc->sc_rsel);
1.1 cube 1132: simple_unlock(&sc->sc_kqlock);
1133: }
1134: }
1135: revents |= events & (POLLOUT|POLLWRNORM);
1136:
1137: return (revents);
1138: }
1139:
1140: static struct filterops tap_read_filterops = { 1, NULL, tap_kqdetach,
1141: tap_kqread };
1142: static struct filterops tap_seltrue_filterops = { 1, NULL, tap_kqdetach,
1143: filt_seltrue };
1144:
1145: static int
1146: tap_cdev_kqfilter(dev_t dev, struct knote *kn)
1147: {
1148: return tap_dev_kqfilter(minor(dev), kn);
1149: }
1150:
1151: static int
1.41 ad 1152: tap_fops_kqfilter(file_t *fp, struct knote *kn)
1.1 cube 1153: {
1154: return tap_dev_kqfilter((intptr_t)fp->f_data, kn);
1155: }
1156:
1157: static int
1158: tap_dev_kqfilter(int unit, struct knote *kn)
1159: {
1160: struct tap_softc *sc =
1.46 cegger 1161: device_lookup_private(&tap_cd, unit);
1.1 cube 1162:
1163: if (sc == NULL)
1164: return (ENXIO);
1165:
1.44 ad 1166: KERNEL_LOCK(1, NULL);
1.1 cube 1167: switch(kn->kn_filter) {
1168: case EVFILT_READ:
1169: kn->kn_fop = &tap_read_filterops;
1170: break;
1171: case EVFILT_WRITE:
1172: kn->kn_fop = &tap_seltrue_filterops;
1173: break;
1174: default:
1.44 ad 1175: KERNEL_UNLOCK_ONE(NULL);
1.35 pooka 1176: return (EINVAL);
1.1 cube 1177: }
1178:
1179: kn->kn_hook = sc;
1.4 ragge 1180: simple_lock(&sc->sc_kqlock);
1.1 cube 1181: SLIST_INSERT_HEAD(&sc->sc_rsel.sel_klist, kn, kn_selnext);
1182: simple_unlock(&sc->sc_kqlock);
1.44 ad 1183: KERNEL_UNLOCK_ONE(NULL);
1.1 cube 1184: return (0);
1185: }
1186:
1187: static void
1188: tap_kqdetach(struct knote *kn)
1189: {
1190: struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1191:
1.44 ad 1192: KERNEL_LOCK(1, NULL);
1.4 ragge 1193: simple_lock(&sc->sc_kqlock);
1.1 cube 1194: SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
1195: simple_unlock(&sc->sc_kqlock);
1.44 ad 1196: KERNEL_UNLOCK_ONE(NULL);
1.1 cube 1197: }
1198:
1199: static int
1.23 christos 1200: tap_kqread(struct knote *kn, long hint)
1.1 cube 1201: {
1202: struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1203: struct ifnet *ifp = &sc->sc_ec.ec_if;
1204: struct mbuf *m;
1.44 ad 1205: int s, rv;
1.1 cube 1206:
1.44 ad 1207: KERNEL_LOCK(1, NULL);
1.1 cube 1208: s = splnet();
1209: IFQ_POLL(&ifp->if_snd, m);
1210:
1211: if (m == NULL)
1212: kn->kn_data = 0;
1213: else
1214: kn->kn_data = m->m_pkthdr.len;
1215: splx(s);
1.44 ad 1216: rv = (kn->kn_data != 0 ? 1 : 0);
1217: KERNEL_UNLOCK_ONE(NULL);
1218: return rv;
1.1 cube 1219: }
1220:
1221: /*
1222: * sysctl management routines
1223: * You can set the address of an interface through:
1224: * net.link.tap.tap<number>
1225: *
1226: * Note the consistent use of tap_log in order to use
1227: * sysctl_teardown at unload time.
1228: *
1229: * In the kernel you will find a lot of SYSCTL_SETUP blocks. Those
1230: * blocks register a function in a special section of the kernel
1231: * (called a link set) which is used at init_sysctl() time to cycle
1232: * through all those functions to create the kernel's sysctl tree.
1233: *
1234: * It is not (currently) possible to use link sets in a LKM, so the
1235: * easiest is to simply call our own setup routine at load time.
1236: *
1237: * In the SYSCTL_SETUP blocks you find in the kernel, nodes have the
1238: * CTLFLAG_PERMANENT flag, meaning they cannot be removed. Once the
1239: * whole kernel sysctl tree is built, it is not possible to add any
1240: * permanent node.
1241: *
1242: * It should be noted that we're not saving the sysctlnode pointer
1243: * we are returned when creating the "tap" node. That structure
1244: * cannot be trusted once out of the calling function, as it might
1245: * get reused. So we just save the MIB number, and always give the
1246: * full path starting from the root for later calls to sysctl_createv
1247: * and sysctl_destroyv.
1248: */
1249: SYSCTL_SETUP(sysctl_tap_setup, "sysctl net.link.tap subtree setup")
1250: {
1.10 atatat 1251: const struct sysctlnode *node;
1.1 cube 1252: int error = 0;
1253:
1254: if ((error = sysctl_createv(clog, 0, NULL, NULL,
1255: CTLFLAG_PERMANENT,
1256: CTLTYPE_NODE, "net", NULL,
1257: NULL, 0, NULL, 0,
1258: CTL_NET, CTL_EOL)) != 0)
1259: return;
1260:
1261: if ((error = sysctl_createv(clog, 0, NULL, NULL,
1262: CTLFLAG_PERMANENT,
1263: CTLTYPE_NODE, "link", NULL,
1264: NULL, 0, NULL, 0,
1.3 cube 1265: CTL_NET, AF_LINK, CTL_EOL)) != 0)
1.1 cube 1266: return;
1267:
1268: /*
1269: * The first four parameters of sysctl_createv are for management.
1270: *
1271: * The four that follows, here starting with a '0' for the flags,
1272: * describe the node.
1273: *
1274: * The next series of four set its value, through various possible
1275: * means.
1276: *
1277: * Last but not least, the path to the node is described. That path
1278: * is relative to the given root (third argument). Here we're
1279: * starting from the root.
1280: */
1281: if ((error = sysctl_createv(clog, 0, NULL, &node,
1282: CTLFLAG_PERMANENT,
1283: CTLTYPE_NODE, "tap", NULL,
1284: NULL, 0, NULL, 0,
1.3 cube 1285: CTL_NET, AF_LINK, CTL_CREATE, CTL_EOL)) != 0)
1.1 cube 1286: return;
1287: tap_node = node->sysctl_num;
1288: }
1289:
1290: /*
1291: * The helper functions make Andrew Brown's interface really
1292: * shine. It makes possible to create value on the fly whether
1293: * the sysctl value is read or written.
1294: *
1295: * As shown as an example in the man page, the first step is to
1296: * create a copy of the node to have sysctl_lookup work on it.
1297: *
1298: * Here, we have more work to do than just a copy, since we have
1299: * to create the string. The first step is to collect the actual
1300: * value of the node, which is a convenient pointer to the softc
1301: * of the interface. From there we create the string and use it
1302: * as the value, but only for the *copy* of the node.
1303: *
1304: * Then we let sysctl_lookup do the magic, which consists in
1305: * setting oldp and newp as required by the operation. When the
1306: * value is read, that means that the string will be copied to
1307: * the user, and when it is written, the new value will be copied
1308: * over in the addr array.
1309: *
1310: * If newp is NULL, the user was reading the value, so we don't
1311: * have anything else to do. If a new value was written, we
1312: * have to check it.
1313: *
1314: * If it is incorrect, we can return an error and leave 'node' as
1315: * it is: since it is a copy of the actual node, the change will
1316: * be forgotten.
1317: *
1318: * Upon a correct input, we commit the change to the ifnet
1319: * structure of our interface.
1320: */
1321: static int
1322: tap_sysctl_handler(SYSCTLFN_ARGS)
1323: {
1324: struct sysctlnode node;
1325: struct tap_softc *sc;
1326: struct ifnet *ifp;
1327: int error;
1328: size_t len;
1.14 christos 1329: char addr[3 * ETHER_ADDR_LEN];
1.32 dyoung 1330: uint8_t enaddr[ETHER_ADDR_LEN];
1.1 cube 1331:
1332: node = *rnode;
1333: sc = node.sysctl_data;
1334: ifp = &sc->sc_ec.ec_if;
1.31 dyoung 1335: (void)ether_snprintf(addr, sizeof(addr), CLLADDR(ifp->if_sadl));
1.1 cube 1336: node.sysctl_data = addr;
1337: error = sysctl_lookup(SYSCTLFN_CALL(&node));
1338: if (error || newp == NULL)
1339: return (error);
1340:
1341: len = strlen(addr);
1342: if (len < 11 || len > 17)
1343: return (EINVAL);
1344:
1345: /* Commit change */
1.36 dyoung 1346: if (ether_nonstatic_aton(enaddr, addr) != 0)
1.1 cube 1347: return (EINVAL);
1.36 dyoung 1348: if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN);
1.1 cube 1349: return (error);
1350: }
CVSweb <webmaster@jp.NetBSD.org>