Wed Mar 18 05:23:45 2009 UTC ()
Pull up following revision(s) (requested by plunky in ticket #575):
	sys/net/if_tap.c: revision 1.54
Deprecate the SIOCSIFPHYADDR ioctl and the sysctl node in favour
of the generic SIOCALIFADDR.
As suggested by cube.


(snj)
diff -r1.47.4.4 -r1.47.4.5 src/sys/net/if_tap.c

cvs diff -r1.47.4.4 -r1.47.4.5 src/sys/net/if_tap.c (expand / switch to unified diff)

--- src/sys/net/if_tap.c 2009/03/18 05:19:59 1.47.4.4
+++ src/sys/net/if_tap.c 2009/03/18 05:23:44 1.47.4.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_tap.c,v 1.47.4.4 2009/03/18 05:19:59 snj Exp $ */ 1/* $NetBSD: if_tap.c,v 1.47.4.5 2009/03/18 05:23:44 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003, 2004, 2008 The NetBSD Foundation. 4 * Copyright (c) 2003, 2004, 2008 The NetBSD Foundation.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -23,78 +23,85 @@ @@ -23,78 +23,85 @@
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * tap(4) is a virtual Ethernet interface. It appears as a real Ethernet 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 31 * device to the system, but can also be accessed by userland through a
32 * character device interface, which allows reading and injecting frames. 32 * character device interface, which allows reading and injecting frames.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.47.4.4 2009/03/18 05:19:59 snj Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: if_tap.c,v 1.47.4.5 2009/03/18 05:23:44 snj Exp $");
37 37
38#if defined(_KERNEL_OPT) 38#if defined(_KERNEL_OPT)
39#include "bpfilter.h" 39#include "bpfilter.h"
 40#include "opt_modular.h"
 41#include "opt_compat_netbsd.h"
40#endif 42#endif
41 43
42#include <sys/param.h> 44#include <sys/param.h>
43#include <sys/systm.h> 45#include <sys/systm.h>
44#include <sys/kernel.h> 46#include <sys/kernel.h>
45#include <sys/malloc.h> 47#include <sys/malloc.h>
46#include <sys/conf.h> 48#include <sys/conf.h>
47#include <sys/device.h> 49#include <sys/device.h>
48#include <sys/file.h> 50#include <sys/file.h>
49#include <sys/filedesc.h> 51#include <sys/filedesc.h>
50#include <sys/ksyms.h> 52#include <sys/ksyms.h>
51#include <sys/poll.h> 53#include <sys/poll.h>
 54#include <sys/proc.h>
52#include <sys/select.h> 55#include <sys/select.h>
53#include <sys/sockio.h> 56#include <sys/sockio.h>
 57#if defined(COMPAT_40) || defined(MODULAR)
54#include <sys/sysctl.h> 58#include <sys/sysctl.h>
 59#endif
55#include <sys/kauth.h> 60#include <sys/kauth.h>
56#include <sys/mutex.h> 61#include <sys/mutex.h>
57#include <sys/simplelock.h> 62#include <sys/simplelock.h>
58#include <sys/intr.h> 63#include <sys/intr.h>
59 64
60#include <net/if.h> 65#include <net/if.h>
61#include <net/if_dl.h> 66#include <net/if_dl.h>
62#include <net/if_ether.h> 67#include <net/if_ether.h>
63#include <net/if_media.h> 68#include <net/if_media.h>
64#include <net/if_tap.h> 69#include <net/if_tap.h>
65#if NBPFILTER > 0 70#if NBPFILTER > 0
66#include <net/bpf.h> 71#include <net/bpf.h>
67#endif 72#endif
68 73
69#include <compat/sys/sockio.h> 74#include <compat/sys/sockio.h>
70 75
 76#if defined(COMPAT_40) || defined(MODULAR)
71/* 77/*
72 * sysctl node management 78 * sysctl node management
73 * 79 *
74 * It's not really possible to use a SYSCTL_SETUP block with 80 * It's not really possible to use a SYSCTL_SETUP block with
75 * current LKM implementation, so it is easier to just define 81 * current LKM implementation, so it is easier to just define
76 * our own function. 82 * our own function.
77 * 83 *
78 * The handler function is a "helper" in Andrew Brown's sysctl 84 * The handler function is a "helper" in Andrew Brown's sysctl
79 * framework terminology. It is used as a gateway for sysctl 85 * framework terminology. It is used as a gateway for sysctl
80 * requests over the nodes. 86 * requests over the nodes.
81 * 87 *
82 * tap_log allows the module to log creations of nodes and 88 * tap_log allows the module to log creations of nodes and
83 * destroy them all at once using sysctl_teardown. 89 * destroy them all at once using sysctl_teardown.
84 */ 90 */
85static int tap_node; 91static int tap_node;
86static int tap_sysctl_handler(SYSCTLFN_PROTO); 92static int tap_sysctl_handler(SYSCTLFN_PROTO);
87SYSCTL_SETUP_PROTO(sysctl_tap_setup); 93SYSCTL_SETUP_PROTO(sysctl_tap_setup);
 94#endif
88 95
89/* 96/*
90 * Since we're an Ethernet device, we need the 3 following 97 * Since we're an Ethernet device, we need the 3 following
91 * components: a leading struct device, a struct ethercom, 98 * components: a leading struct device, a struct ethercom,
92 * and also a struct ifmedia since we don't attach a PHY to 99 * and also a struct ifmedia since we don't attach a PHY to
93 * ourselves. We could emulate one, but there's no real 100 * ourselves. We could emulate one, but there's no real
94 * point. 101 * point.
95 */ 102 */
96 103
97struct tap_softc { 104struct tap_softc {
98 device_t sc_dev; 105 device_t sc_dev;
99 struct ifmedia sc_im; 106 struct ifmedia sc_im;
100 struct ethercom sc_ec; 107 struct ethercom sc_ec;
@@ -187,27 +194,29 @@ static void tap_mediastatus(struct ifnet @@ -187,27 +194,29 @@ static void tap_mediastatus(struct ifnet
187 194
188/* 195/*
189 * Those are needed by the ifnet interface, and would typically be 196 * Those are needed by the ifnet interface, and would typically be
190 * there for any network interface driver. 197 * there for any network interface driver.
191 * Some other routines are optional: watchdog and drain. 198 * Some other routines are optional: watchdog and drain.
192 */ 199 */
193 200
194static void tap_start(struct ifnet *); 201static void tap_start(struct ifnet *);
195static void tap_stop(struct ifnet *, int); 202static void tap_stop(struct ifnet *, int);
196static int tap_init(struct ifnet *); 203static int tap_init(struct ifnet *);
197static int tap_ioctl(struct ifnet *, u_long, void *); 204static int tap_ioctl(struct ifnet *, u_long, void *);
198 205
199/* Internal functions */ 206/* Internal functions */
 207#if defined(COMPAT_40) || defined(MODULAR)
200static int tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *); 208static int tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *);
 209#endif
201static void tap_softintr(void *); 210static void tap_softintr(void *);
202 211
203/* 212/*
204 * tap is a clonable interface, although it is highly unrealistic for 213 * tap is a clonable interface, although it is highly unrealistic for
205 * an Ethernet device. 214 * an Ethernet device.
206 * 215 *
207 * Here are the bits needed for a clonable interface. 216 * Here are the bits needed for a clonable interface.
208 */ 217 */
209static int tap_clone_create(struct if_clone *, int); 218static int tap_clone_create(struct if_clone *, int);
210static int tap_clone_destroy(struct ifnet *); 219static int tap_clone_destroy(struct ifnet *);
211 220
212struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap", 221struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap",
213 tap_clone_create, 222 tap_clone_create,
@@ -236,33 +245,35 @@ tapattach(int n) @@ -236,33 +245,35 @@ tapattach(int n)
236/* Pretty much useless for a pseudo-device */ 245/* Pretty much useless for a pseudo-device */
237static int 246static int
238tap_match(device_t parent, cfdata_t cfdata, void *arg) 247tap_match(device_t parent, cfdata_t cfdata, void *arg)
239{ 248{
240 249
241 return (1); 250 return (1);
242} 251}
243 252
244void 253void
245tap_attach(device_t parent, device_t self, void *aux) 254tap_attach(device_t parent, device_t self, void *aux)
246{ 255{
247 struct tap_softc *sc = device_private(self); 256 struct tap_softc *sc = device_private(self);
248 struct ifnet *ifp; 257 struct ifnet *ifp;
 258#if defined(COMPAT_40) || defined(MODULAR)
249 const struct sysctlnode *node; 259 const struct sysctlnode *node;
 260 int error;
 261#endif
250 uint8_t enaddr[ETHER_ADDR_LEN] = 262 uint8_t enaddr[ETHER_ADDR_LEN] =
251 { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff }; 263 { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
252 char enaddrstr[3 * ETHER_ADDR_LEN]; 264 char enaddrstr[3 * ETHER_ADDR_LEN];
253 struct timeval tv; 265 struct timeval tv;
254 uint32_t ui; 266 uint32_t ui;
255 int error; 
256 267
257 sc->sc_dev = self; 268 sc->sc_dev = self;
258 sc->sc_sih = softint_establish(SOFTINT_CLOCK, tap_softintr, sc); 269 sc->sc_sih = softint_establish(SOFTINT_CLOCK, tap_softintr, sc);
259 270
260 if (!pmf_device_register(self, NULL, NULL)) 271 if (!pmf_device_register(self, NULL, NULL))
261 aprint_error_dev(self, "couldn't establish power handler\n"); 272 aprint_error_dev(self, "couldn't establish power handler\n");
262 273
263 /* 274 /*
264 * In order to obtain unique initial Ethernet address on a host, 275 * In order to obtain unique initial Ethernet address on a host,
265 * do some randomisation using the current uptime. It's not meant 276 * do some randomisation using the current uptime. It's not meant
266 * for anything but avoiding hard-coding an address. 277 * for anything but avoiding hard-coding an address.
267 */ 278 */
268 getmicrouptime(&tv); 279 getmicrouptime(&tv);
@@ -302,48 +313,50 @@ tap_attach(device_t parent, device_t sel @@ -302,48 +313,50 @@ tap_attach(device_t parent, device_t sel
302 ifp->if_stop = tap_stop; 313 ifp->if_stop = tap_stop;
303 ifp->if_init = tap_init; 314 ifp->if_init = tap_init;
304 IFQ_SET_READY(&ifp->if_snd); 315 IFQ_SET_READY(&ifp->if_snd);
305 316
306 sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU; 317 sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
307 318
308 /* Those steps are mandatory for an Ethernet driver, the fisrt call 319 /* Those steps are mandatory for an Ethernet driver, the fisrt call
309 * being common to all network interface drivers. */ 320 * being common to all network interface drivers. */
310 if_attach(ifp); 321 if_attach(ifp);
311 ether_ifattach(ifp, enaddr); 322 ether_ifattach(ifp, enaddr);
312 323
313 sc->sc_flags = 0; 324 sc->sc_flags = 0;
314 325
 326#if defined(COMPAT_40) || defined(MODULAR)
315 /* 327 /*
316 * Add a sysctl node for that interface. 328 * Add a sysctl node for that interface.
317 * 329 *
318 * The pointer transmitted is not a string, but instead a pointer to 330 * 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 331 * 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 332 * the fly in the helper function of the node. See the comments for
321 * tap_sysctl_handler for details. 333 * tap_sysctl_handler for details.
322 * 334 *
323 * Usually sysctl_createv is called with CTL_CREATE as the before-last 335 * Usually sysctl_createv is called with CTL_CREATE as the before-last
324 * component. However, we can allocate a number ourselves, as we are 336 * 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 337 * 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 338 * unit number is conveniently used to number the node. CTL_CREATE
327 * would just work, too. 339 * would just work, too.
328 */ 340 */
329 if ((error = sysctl_createv(NULL, 0, NULL, 341 if ((error = sysctl_createv(NULL, 0, NULL,
330 &node, CTLFLAG_READWRITE, 342 &node, CTLFLAG_READWRITE,
331 CTLTYPE_STRING, device_xname(self), NULL, 343 CTLTYPE_STRING, device_xname(self), NULL,
332 tap_sysctl_handler, 0, sc, 18, 344 tap_sysctl_handler, 0, sc, 18,
333 CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev), 345 CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev),
334 CTL_EOL)) != 0) 346 CTL_EOL)) != 0)
335 aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n", 347 aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n",
336 error); 348 error);
 349#endif
337 350
338 /* 351 /*
339 * Initialize the two locks for the device. 352 * Initialize the two locks for the device.
340 * 353 *
341 * We need a lock here because even though the tap device can be 354 * 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 355 * opened only once, the file descriptor might be passed to another
343 * process, say a fork(2)ed child. 356 * process, say a fork(2)ed child.
344 * 357 *
345 * The Giant saves us from most of the hassle, but since the read 358 * 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 359 * 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. 360 * the same moment and both try and dequeue a single packet.
348 * 361 *
349 * The queue for event listeners (used by kqueue(9), see below) has 362 * The queue for event listeners (used by kqueue(9), see below) has
@@ -355,45 +368,50 @@ tap_attach(device_t parent, device_t sel @@ -355,45 +368,50 @@ tap_attach(device_t parent, device_t sel
355 368
356 selinit(&sc->sc_rsel); 369 selinit(&sc->sc_rsel);
357} 370}
358 371
359/* 372/*
360 * When detaching, we do the inverse of what is done in the attach 373 * When detaching, we do the inverse of what is done in the attach
361 * routine, in reversed order. 374 * routine, in reversed order.
362 */ 375 */
363static int 376static int
364tap_detach(device_t self, int flags) 377tap_detach(device_t self, int flags)
365{ 378{
366 struct tap_softc *sc = device_private(self); 379 struct tap_softc *sc = device_private(self);
367 struct ifnet *ifp = &sc->sc_ec.ec_if; 380 struct ifnet *ifp = &sc->sc_ec.ec_if;
368 int error, s; 381#if defined(COMPAT_40) || defined(MODULAR)
 382 int error;
 383#endif
 384 int s;
369 385
370 sc->sc_flags |= TAP_GOING; 386 sc->sc_flags |= TAP_GOING;
371 s = splnet(); 387 s = splnet();
372 tap_stop(ifp, 1); 388 tap_stop(ifp, 1);
373 if_down(ifp); 389 if_down(ifp);
374 splx(s); 390 splx(s);
375 391
376 softint_disestablish(sc->sc_sih); 392 softint_disestablish(sc->sc_sih);
377 393
 394#if defined(COMPAT_40) || defined(MODULAR)
378 /* 395 /*
379 * Destroying a single leaf is a very straightforward operation using 396 * Destroying a single leaf is a very straightforward operation using
380 * sysctl_destroyv. One should be sure to always end the path with 397 * sysctl_destroyv. One should be sure to always end the path with
381 * CTL_EOL. 398 * CTL_EOL.
382 */ 399 */
383 if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node, 400 if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node,
384 device_unit(sc->sc_dev), CTL_EOL)) != 0) 401 device_unit(sc->sc_dev), CTL_EOL)) != 0)
385 aprint_error_dev(self, 402 aprint_error_dev(self,
386 "sysctl_destroyv returned %d, ignoring\n", error); 403 "sysctl_destroyv returned %d, ignoring\n", error);
 404#endif
387 ether_ifdetach(ifp); 405 ether_ifdetach(ifp);
388 if_detach(ifp); 406 if_detach(ifp);
389 ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY); 407 ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY);
390 seldestroy(&sc->sc_rsel); 408 seldestroy(&sc->sc_rsel);
391 mutex_destroy(&sc->sc_rdlock); 409 mutex_destroy(&sc->sc_rdlock);
392 410
393 pmf_device_deregister(self); 411 pmf_device_deregister(self);
394 412
395 return (0); 413 return (0);
396} 414}
397 415
398/* 416/*
399 * This function is called by the ifmedia layer to notify the driver 417 * This function is called by the ifmedia layer to notify the driver
@@ -511,57 +529,61 @@ tap_ioctl(struct ifnet *ifp, u_long cmd, @@ -511,57 +529,61 @@ tap_ioctl(struct ifnet *ifp, u_long cmd,
511 struct ifreq *ifr = (struct ifreq *)data; 529 struct ifreq *ifr = (struct ifreq *)data;
512 int s, error; 530 int s, error;
513 531
514 s = splnet(); 532 s = splnet();
515 533
516 switch (cmd) { 534 switch (cmd) {
517#ifdef OSIOCSIFMEDIA 535#ifdef OSIOCSIFMEDIA
518 case OSIOCSIFMEDIA: 536 case OSIOCSIFMEDIA:
519#endif 537#endif
520 case SIOCSIFMEDIA: 538 case SIOCSIFMEDIA:
521 case SIOCGIFMEDIA: 539 case SIOCGIFMEDIA:
522 error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd); 540 error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd);
523 break; 541 break;
 542#if defined(COMPAT_40) || defined(MODULAR)
524 case SIOCSIFPHYADDR: 543 case SIOCSIFPHYADDR:
525 error = tap_lifaddr(ifp, cmd, (struct ifaliasreq *)data); 544 error = tap_lifaddr(ifp, cmd, (struct ifaliasreq *)data);
526 break; 545 break;
 546#endif
527 default: 547 default:
528 error = ether_ioctl(ifp, cmd, data); 548 error = ether_ioctl(ifp, cmd, data);
529 if (error == ENETRESET) 549 if (error == ENETRESET)
530 error = 0; 550 error = 0;
531 break; 551 break;
532 } 552 }
533 553
534 splx(s); 554 splx(s);
535 555
536 return (error); 556 return (error);
537} 557}
538 558
 559#if defined(COMPAT_40) || defined(MODULAR)
539/* 560/*
540 * Helper function to set Ethernet address. This shouldn't be done there, 561 * Helper function to set Ethernet address. This has been replaced by
541 * and should actually be available to all Ethernet drivers, real or not. 562 * the generic SIOCALIFADDR ioctl on a PF_LINK socket.
542 */ 563 */
543static int 564static int
544tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra) 565tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra)
545{ 566{
546 const struct sockaddr *sa = &ifra->ifra_addr; 567 const struct sockaddr *sa = &ifra->ifra_addr;
547 568
548 if (sa->sa_family != AF_LINK) 569 if (sa->sa_family != AF_LINK)
549 return (EINVAL); 570 return (EINVAL);
550 571
551 if_set_sadl(ifp, sa->sa_data, ETHER_ADDR_LEN); 572 if_set_sadl(ifp, sa->sa_data, ETHER_ADDR_LEN);
552 573
553 return (0); 574 return (0);
554} 575}
 576#endif
555 577
556/* 578/*
557 * _init() would typically be called when an interface goes up, 579 * _init() would typically be called when an interface goes up,
558 * meaning it should configure itself into the state in which it 580 * meaning it should configure itself into the state in which it
559 * can send packets. 581 * can send packets.
560 */ 582 */
561static int 583static int
562tap_init(struct ifnet *ifp) 584tap_init(struct ifnet *ifp)
563{ 585{
564 ifp->if_flags |= IFF_RUNNING; 586 ifp->if_flags |= IFF_RUNNING;
565 587
566 tap_start(ifp); 588 tap_start(ifp);
567 589
@@ -1208,26 +1230,27 @@ tap_kqread(struct knote *kn, long hint) @@ -1208,26 +1230,27 @@ tap_kqread(struct knote *kn, long hint)
1208 s = splnet(); 1230 s = splnet();
1209 IFQ_POLL(&ifp->if_snd, m); 1231 IFQ_POLL(&ifp->if_snd, m);
1210 1232
1211 if (m == NULL) 1233 if (m == NULL)
1212 kn->kn_data = 0; 1234 kn->kn_data = 0;
1213 else 1235 else
1214 kn->kn_data = m->m_pkthdr.len; 1236 kn->kn_data = m->m_pkthdr.len;
1215 splx(s); 1237 splx(s);
1216 rv = (kn->kn_data != 0 ? 1 : 0); 1238 rv = (kn->kn_data != 0 ? 1 : 0);
1217 KERNEL_UNLOCK_ONE(NULL); 1239 KERNEL_UNLOCK_ONE(NULL);
1218 return rv; 1240 return rv;
1219} 1241}
1220 1242
 1243#if defined(COMPAT_40) || defined(MODULAR)
1221/* 1244/*
1222 * sysctl management routines 1245 * sysctl management routines
1223 * You can set the address of an interface through: 1246 * You can set the address of an interface through:
1224 * net.link.tap.tap<number> 1247 * net.link.tap.tap<number>
1225 * 1248 *
1226 * Note the consistent use of tap_log in order to use 1249 * Note the consistent use of tap_log in order to use
1227 * sysctl_teardown at unload time. 1250 * sysctl_teardown at unload time.
1228 * 1251 *
1229 * In the kernel you will find a lot of SYSCTL_SETUP blocks. Those 1252 * 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 1253 * 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 1254 * (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. 1255 * through all those functions to create the kernel's sysctl tree.
1233 * 1256 *
@@ -1338,13 +1361,14 @@ tap_sysctl_handler(SYSCTLFN_ARGS) @@ -1338,13 +1361,14 @@ tap_sysctl_handler(SYSCTLFN_ARGS)
1338 if (error || newp == NULL) 1361 if (error || newp == NULL)
1339 return (error); 1362 return (error);
1340 1363
1341 len = strlen(addr); 1364 len = strlen(addr);
1342 if (len < 11 || len > 17) 1365 if (len < 11 || len > 17)
1343 return (EINVAL); 1366 return (EINVAL);
1344 1367
1345 /* Commit change */ 1368 /* Commit change */
1346 if (ether_nonstatic_aton(enaddr, addr) != 0) 1369 if (ether_nonstatic_aton(enaddr, addr) != 0)
1347 return (EINVAL); 1370 return (EINVAL);
1348 if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN); 1371 if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN);
1349 return (error); 1372 return (error);
1350} 1373}
 1374#endif