| @@ -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 | */ |
85 | static int tap_node; | | 91 | static int tap_node; |
86 | static int tap_sysctl_handler(SYSCTLFN_PROTO); | | 92 | static int tap_sysctl_handler(SYSCTLFN_PROTO); |
87 | SYSCTL_SETUP_PROTO(sysctl_tap_setup); | | 93 | SYSCTL_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 | |
97 | struct tap_softc { | | 104 | struct 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 | |
194 | static void tap_start(struct ifnet *); | | 201 | static void tap_start(struct ifnet *); |
195 | static void tap_stop(struct ifnet *, int); | | 202 | static void tap_stop(struct ifnet *, int); |
196 | static int tap_init(struct ifnet *); | | 203 | static int tap_init(struct ifnet *); |
197 | static int tap_ioctl(struct ifnet *, u_long, void *); | | 204 | static int tap_ioctl(struct ifnet *, u_long, void *); |
198 | | | 205 | |
199 | /* Internal functions */ | | 206 | /* Internal functions */ |
| | | 207 | #if defined(COMPAT_40) || defined(MODULAR) |
200 | static int tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *); | | 208 | static int tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *); |
| | | 209 | #endif |
201 | static void tap_softintr(void *); | | 210 | static 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 | */ |
209 | static int tap_clone_create(struct if_clone *, int); | | 218 | static int tap_clone_create(struct if_clone *, int); |
210 | static int tap_clone_destroy(struct ifnet *); | | 219 | static int tap_clone_destroy(struct ifnet *); |
211 | | | 220 | |
212 | struct if_clone tap_cloners = IF_CLONE_INITIALIZER("tap", | | 221 | struct 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 */ |
237 | static int | | 246 | static int |
238 | tap_match(device_t parent, cfdata_t cfdata, void *arg) | | 247 | tap_match(device_t parent, cfdata_t cfdata, void *arg) |
239 | { | | 248 | { |
240 | | | 249 | |
241 | return (1); | | 250 | return (1); |
242 | } | | 251 | } |
243 | | | 252 | |
244 | void | | 253 | void |
245 | tap_attach(device_t parent, device_t self, void *aux) | | 254 | tap_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 | */ |
363 | static int | | 376 | static int |
364 | tap_detach(device_t self, int flags) | | 377 | tap_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 | */ |
543 | static int | | 564 | static int |
544 | tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra) | | 565 | tap_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 | */ |
561 | static int | | 583 | static int |
562 | tap_init(struct ifnet *ifp) | | 584 | tap_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 |