Line data Source code
1 : /* $OpenBSD: if_tun.c,v 1.181 2018/02/24 07:20:04 dlg Exp $ */
2 : /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
3 :
4 : /*
5 : * Copyright (c) 1988, Julian Onions <Julian.Onions@nexor.co.uk>
6 : * Nottingham University 1987.
7 : * All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : * 1. Redistributions of source code must retain the above copyright
13 : * notice, this list of conditions and the following disclaimer.
14 : * 2. Redistributions in binary form must reproduce the above copyright
15 : * notice, this list of conditions and the following disclaimer in the
16 : * documentation and/or other materials provided with the distribution.
17 : *
18 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : */
29 :
30 : /*
31 : * This driver takes packets off the IP i/f and hands them up to a
32 : * user process to have its wicked way with. This driver has its
33 : * roots in a similar driver written by Phil Cockcroft (formerly) at
34 : * UCL. This driver is based much more on read/write/select mode of
35 : * operation though.
36 : */
37 :
38 : /* #define TUN_DEBUG 9 */
39 :
40 : #include <sys/param.h>
41 : #include <sys/kernel.h>
42 : #include <sys/proc.h>
43 : #include <sys/systm.h>
44 : #include <sys/mbuf.h>
45 : #include <sys/protosw.h>
46 : #include <sys/socket.h>
47 : #include <sys/ioctl.h>
48 : #include <sys/errno.h>
49 : #include <sys/syslog.h>
50 : #include <sys/selinfo.h>
51 : #include <sys/fcntl.h>
52 : #include <sys/time.h>
53 : #include <sys/device.h>
54 : #include <sys/vnode.h>
55 : #include <sys/signalvar.h>
56 : #include <sys/poll.h>
57 : #include <sys/conf.h>
58 :
59 :
60 : #include <net/if.h>
61 : #include <net/if_types.h>
62 : #include <net/netisr.h>
63 : #include <net/rtable.h>
64 :
65 : #include <netinet/in.h>
66 : #include <netinet/if_ether.h>
67 :
68 : #ifdef PIPEX
69 : #include <net/pipex.h>
70 : #endif
71 :
72 : #include "bpfilter.h"
73 : #if NBPFILTER > 0
74 : #include <net/bpf.h>
75 : #endif
76 :
77 : #include <net/if_tun.h>
78 :
79 : struct tun_softc {
80 : struct arpcom arpcom; /* ethernet common data */
81 : struct selinfo tun_rsel; /* read select */
82 : struct selinfo tun_wsel; /* write select (not used) */
83 : LIST_ENTRY(tun_softc) entry; /* all tunnel interfaces */
84 : int tun_unit;
85 : uid_t tun_siguid; /* uid for process that set tun_pgid */
86 : uid_t tun_sigeuid; /* euid for process that set tun_pgid */
87 : pid_t tun_pgid; /* the process group - if any */
88 : u_short tun_flags; /* misc flags */
89 : #define tun_if arpcom.ac_if
90 : #ifdef PIPEX
91 : struct pipex_iface_context pipex_iface; /* pipex context */
92 : #endif
93 : };
94 :
95 : #ifdef TUN_DEBUG
96 : int tundebug = TUN_DEBUG;
97 : #define TUNDEBUG(a) (tundebug? printf a : 0)
98 : #else
99 : #define TUNDEBUG(a) /* (tundebug? printf a : 0) */
100 : #endif
101 :
102 : /* Only these IFF flags are changeable by TUNSIFINFO */
103 : #define TUN_IFF_FLAGS (IFF_UP|IFF_POINTOPOINT|IFF_MULTICAST|IFF_BROADCAST)
104 :
105 : void tunattach(int);
106 :
107 : /* cdev functions */
108 : int tunopen(dev_t, int, int, struct proc *);
109 : int tunclose(dev_t, int, int, struct proc *);
110 : int tunioctl(dev_t, u_long, caddr_t, int, struct proc *);
111 : int tunread(dev_t, struct uio *, int);
112 : int tunwrite(dev_t, struct uio *, int);
113 : int tunpoll(dev_t, int, struct proc *);
114 : int tunkqfilter(dev_t, struct knote *);
115 :
116 : int tapopen(dev_t, int, int, struct proc *);
117 : int tapclose(dev_t, int, int, struct proc *);
118 : int tapioctl(dev_t, u_long, caddr_t, int, struct proc *);
119 : int tapread(dev_t, struct uio *, int);
120 : int tapwrite(dev_t, struct uio *, int);
121 : int tappoll(dev_t, int, struct proc *);
122 : int tapkqfilter(dev_t, struct knote *);
123 :
124 : int tun_dev_open(struct tun_softc *, int, int, struct proc *);
125 : int tun_dev_close(struct tun_softc *, int, int, struct proc *);
126 : int tun_dev_ioctl(struct tun_softc *, u_long, caddr_t, int, struct proc *);
127 : int tun_dev_read(struct tun_softc *, struct uio *, int);
128 : int tun_dev_write(struct tun_softc *, struct uio *, int);
129 : int tun_dev_poll(struct tun_softc *, int, struct proc *);
130 : int tun_dev_kqfilter(struct tun_softc *, struct knote *);
131 :
132 :
133 : int tun_ioctl(struct ifnet *, u_long, caddr_t);
134 : int tun_output(struct ifnet *, struct mbuf *, struct sockaddr *,
135 : struct rtentry *);
136 : int tun_clone_create(struct if_clone *, int);
137 : int tap_clone_create(struct if_clone *, int);
138 : int tun_create(struct if_clone *, int, int);
139 : int tun_clone_destroy(struct ifnet *);
140 : static inline struct tun_softc *tun_lookup(int);
141 : static inline struct tun_softc *tap_lookup(int);
142 : void tun_wakeup(struct tun_softc *);
143 : int tun_init(struct tun_softc *);
144 : void tun_start(struct ifnet *);
145 : int filt_tunread(struct knote *, long);
146 : int filt_tunwrite(struct knote *, long);
147 : void filt_tunrdetach(struct knote *);
148 : void filt_tunwdetach(struct knote *);
149 : void tun_link_state(struct tun_softc *);
150 :
151 : struct filterops tunread_filtops =
152 : { 1, NULL, filt_tunrdetach, filt_tunread};
153 :
154 : struct filterops tunwrite_filtops =
155 : { 1, NULL, filt_tunwdetach, filt_tunwrite};
156 :
157 : LIST_HEAD(, tun_softc) tun_softc_list;
158 : LIST_HEAD(, tun_softc) tap_softc_list;
159 :
160 : struct if_clone tun_cloner =
161 : IF_CLONE_INITIALIZER("tun", tun_clone_create, tun_clone_destroy);
162 :
163 : struct if_clone tap_cloner =
164 : IF_CLONE_INITIALIZER("tap", tap_clone_create, tun_clone_destroy);
165 :
166 : void
167 0 : tunattach(int n)
168 : {
169 0 : LIST_INIT(&tun_softc_list);
170 0 : LIST_INIT(&tap_softc_list);
171 0 : if_clone_attach(&tun_cloner);
172 0 : if_clone_attach(&tap_cloner);
173 : #ifdef PIPEX
174 0 : pipex_init();
175 : #endif
176 0 : }
177 :
178 : int
179 0 : tun_clone_create(struct if_clone *ifc, int unit)
180 : {
181 0 : return (tun_create(ifc, unit, 0));
182 : }
183 :
184 : int
185 0 : tap_clone_create(struct if_clone *ifc, int unit)
186 : {
187 0 : return (tun_create(ifc, unit, TUN_LAYER2));
188 : }
189 :
190 : int
191 0 : tun_create(struct if_clone *ifc, int unit, int flags)
192 : {
193 : struct tun_softc *tp;
194 : struct ifnet *ifp;
195 :
196 0 : tp = malloc(sizeof(*tp), M_DEVBUF, M_WAITOK|M_ZERO);
197 0 : tp->tun_unit = unit;
198 0 : tp->tun_flags = TUN_INITED|TUN_STAYUP;
199 :
200 0 : ifp = &tp->tun_if;
201 0 : snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", ifc->ifc_name,
202 : unit);
203 0 : ifp->if_softc = tp;
204 :
205 0 : ifp->if_ioctl = tun_ioctl;
206 0 : ifp->if_output = tun_output;
207 0 : ifp->if_start = tun_start;
208 0 : ifp->if_hardmtu = TUNMRU;
209 0 : ifp->if_link_state = LINK_STATE_DOWN;
210 0 : IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
211 :
212 0 : if ((flags & TUN_LAYER2) == 0) {
213 0 : tp->tun_flags &= ~TUN_LAYER2;
214 0 : ifp->if_mtu = ETHERMTU;
215 0 : ifp->if_flags = (IFF_POINTOPOINT|IFF_MULTICAST);
216 0 : ifp->if_type = IFT_TUNNEL;
217 0 : ifp->if_hdrlen = sizeof(u_int32_t);
218 0 : ifp->if_rtrequest = p2p_rtrequest;
219 :
220 0 : if_attach(ifp);
221 0 : if_alloc_sadl(ifp);
222 : #if NBPFILTER > 0
223 0 : bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
224 : #endif
225 0 : LIST_INSERT_HEAD(&tun_softc_list, tp, entry);
226 0 : } else {
227 0 : tp->tun_flags |= TUN_LAYER2;
228 0 : ether_fakeaddr(ifp);
229 0 : ifp->if_flags =
230 : (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
231 0 : ifp->if_capabilities = IFCAP_VLAN_MTU;
232 :
233 0 : if_attach(ifp);
234 0 : ether_ifattach(ifp);
235 :
236 0 : LIST_INSERT_HEAD(&tap_softc_list, tp, entry);
237 : }
238 :
239 : #ifdef PIPEX
240 0 : if ((tp->tun_flags & TUN_LAYER2) == 0)
241 0 : pipex_iface_init(&tp->pipex_iface, ifp);
242 : #endif
243 :
244 0 : return (0);
245 : }
246 :
247 : int
248 0 : tun_clone_destroy(struct ifnet *ifp)
249 : {
250 0 : struct tun_softc *tp = ifp->if_softc;
251 : int s;
252 :
253 : #ifdef PIPEX
254 0 : if ((tp->tun_flags & TUN_LAYER2) == 0)
255 0 : pipex_iface_fini(&tp->pipex_iface);
256 : #endif
257 0 : tun_wakeup(tp);
258 :
259 0 : s = splhigh();
260 0 : klist_invalidate(&tp->tun_rsel.si_note);
261 0 : klist_invalidate(&tp->tun_wsel.si_note);
262 0 : splx(s);
263 :
264 0 : LIST_REMOVE(tp, entry);
265 :
266 0 : if (tp->tun_flags & TUN_LAYER2)
267 0 : ether_ifdetach(ifp);
268 :
269 0 : if_detach(ifp);
270 :
271 0 : free(tp, M_DEVBUF, sizeof *tp);
272 0 : return (0);
273 : }
274 :
275 : static inline struct tun_softc *
276 0 : tun_lookup(int unit)
277 : {
278 : struct tun_softc *tp;
279 :
280 0 : LIST_FOREACH(tp, &tun_softc_list, entry)
281 0 : if (tp->tun_unit == unit)
282 0 : return (tp);
283 0 : return (NULL);
284 0 : }
285 :
286 : static inline struct tun_softc *
287 0 : tap_lookup(int unit)
288 : {
289 : struct tun_softc *tp;
290 :
291 0 : LIST_FOREACH(tp, &tap_softc_list, entry)
292 0 : if (tp->tun_unit == unit)
293 0 : return (tp);
294 0 : return (NULL);
295 0 : }
296 :
297 : /*
298 : * tunnel open - must be superuser & the device must be
299 : * configured in
300 : */
301 : int
302 0 : tunopen(dev_t dev, int flag, int mode, struct proc *p)
303 : {
304 : struct tun_softc *tp;
305 0 : unsigned int rdomain = rtable_l2(p->p_p->ps_rtableid);
306 :
307 0 : if ((tp = tun_lookup(minor(dev))) == NULL) { /* create on demand */
308 0 : char xname[IFNAMSIZ];
309 : int error;
310 :
311 0 : snprintf(xname, sizeof(xname), "%s%d", "tun", minor(dev));
312 0 : NET_LOCK();
313 0 : error = if_clone_create(xname, rdomain);
314 0 : NET_UNLOCK();
315 0 : if (error != 0)
316 0 : return (error);
317 :
318 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
319 0 : return (ENXIO);
320 0 : tp->tun_flags &= ~TUN_STAYUP;
321 0 : }
322 :
323 0 : return (tun_dev_open(tp, flag, mode, p));
324 0 : }
325 :
326 : int
327 0 : tapopen(dev_t dev, int flag, int mode, struct proc *p)
328 : {
329 : struct tun_softc *tp;
330 0 : unsigned int rdomain = rtable_l2(p->p_p->ps_rtableid);
331 :
332 0 : if ((tp = tap_lookup(minor(dev))) == NULL) { /* create on demand */
333 0 : char xname[IFNAMSIZ];
334 : int error;
335 :
336 0 : snprintf(xname, sizeof(xname), "%s%d", "tap", minor(dev));
337 0 : NET_LOCK();
338 0 : error = if_clone_create(xname, rdomain);
339 0 : NET_UNLOCK();
340 0 : if (error != 0)
341 0 : return (error);
342 :
343 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
344 0 : return (ENXIO);
345 0 : tp->tun_flags &= ~TUN_STAYUP;
346 0 : }
347 :
348 0 : return (tun_dev_open(tp, flag, mode, p));
349 0 : }
350 :
351 : int
352 0 : tun_dev_open(struct tun_softc *tp, int flag, int mode, struct proc *p)
353 : {
354 : struct ifnet *ifp;
355 :
356 0 : if (tp->tun_flags & TUN_OPEN)
357 0 : return (EBUSY);
358 :
359 0 : ifp = &tp->tun_if;
360 0 : tp->tun_flags |= TUN_OPEN;
361 0 : if (flag & FNONBLOCK)
362 0 : tp->tun_flags |= TUN_NBIO;
363 :
364 : /* automatically mark the interface running on open */
365 0 : ifp->if_flags |= IFF_RUNNING;
366 0 : tun_link_state(tp);
367 :
368 : TUNDEBUG(("%s: open\n", ifp->if_xname));
369 0 : return (0);
370 0 : }
371 :
372 : /*
373 : * tunclose - close the device; if closing the real device, flush pending
374 : * output and unless STAYUP bring down and destroy the interface.
375 : */
376 : int
377 0 : tunclose(dev_t dev, int flag, int mode, struct proc *p)
378 : {
379 : struct tun_softc *tp;
380 :
381 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
382 0 : return (ENXIO);
383 0 : return (tun_dev_close(tp, flag, mode, p));
384 0 : }
385 :
386 : int
387 0 : tapclose(dev_t dev, int flag, int mode, struct proc *p)
388 : {
389 : struct tun_softc *tp;
390 :
391 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
392 0 : return (ENXIO);
393 0 : return (tun_dev_close(tp, flag, mode, p));
394 0 : }
395 :
396 : int
397 0 : tun_dev_close(struct tun_softc *tp, int flag, int mode, struct proc *p)
398 : {
399 : int error = 0;
400 : struct ifnet *ifp;
401 :
402 0 : ifp = &tp->tun_if;
403 0 : tp->tun_flags &= ~(TUN_OPEN|TUN_NBIO|TUN_ASYNC);
404 :
405 : /*
406 : * junk all pending output
407 : */
408 0 : ifp->if_flags &= ~IFF_RUNNING;
409 0 : tun_link_state(tp);
410 0 : IFQ_PURGE(&ifp->if_snd);
411 :
412 : TUNDEBUG(("%s: closed\n", ifp->if_xname));
413 :
414 0 : if (!(tp->tun_flags & TUN_STAYUP)) {
415 0 : NET_LOCK();
416 0 : error = if_clone_destroy(ifp->if_xname);
417 0 : NET_UNLOCK();
418 0 : } else {
419 0 : tp->tun_pgid = 0;
420 0 : selwakeup(&tp->tun_rsel);
421 : }
422 :
423 0 : return (error);
424 : }
425 :
426 : int
427 0 : tun_init(struct tun_softc *tp)
428 : {
429 0 : struct ifnet *ifp = &tp->tun_if;
430 : struct ifaddr *ifa;
431 :
432 : TUNDEBUG(("%s: tun_init\n", ifp->if_xname));
433 :
434 0 : ifp->if_flags |= IFF_UP | IFF_RUNNING;
435 :
436 0 : tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR|TUN_BRDADDR);
437 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
438 0 : if (ifa->ifa_addr->sa_family == AF_INET) {
439 : struct sockaddr_in *sin;
440 :
441 0 : sin = satosin(ifa->ifa_addr);
442 0 : if (sin && sin->sin_addr.s_addr)
443 0 : tp->tun_flags |= TUN_IASET;
444 :
445 0 : if (ifp->if_flags & IFF_POINTOPOINT) {
446 0 : sin = satosin(ifa->ifa_dstaddr);
447 0 : if (sin && sin->sin_addr.s_addr)
448 0 : tp->tun_flags |= TUN_DSTADDR;
449 : } else
450 0 : tp->tun_flags &= ~TUN_DSTADDR;
451 :
452 0 : if (ifp->if_flags & IFF_BROADCAST) {
453 0 : sin = satosin(ifa->ifa_broadaddr);
454 0 : if (sin && sin->sin_addr.s_addr)
455 0 : tp->tun_flags |= TUN_BRDADDR;
456 : } else
457 0 : tp->tun_flags &= ~TUN_BRDADDR;
458 0 : }
459 : #ifdef INET6
460 0 : if (ifa->ifa_addr->sa_family == AF_INET6) {
461 : struct sockaddr_in6 *sin6;
462 :
463 0 : sin6 = satosin6(ifa->ifa_addr);
464 0 : if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
465 0 : tp->tun_flags |= TUN_IASET;
466 :
467 0 : if (ifp->if_flags & IFF_POINTOPOINT) {
468 0 : sin6 = satosin6(ifa->ifa_dstaddr);
469 0 : if (sin6 &&
470 0 : !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
471 0 : tp->tun_flags |= TUN_DSTADDR;
472 : } else
473 0 : tp->tun_flags &= ~TUN_DSTADDR;
474 0 : }
475 : #endif /* INET6 */
476 : }
477 :
478 0 : return (0);
479 : }
480 :
481 : /*
482 : * Process an ioctl request.
483 : */
484 : int
485 0 : tun_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
486 : {
487 0 : struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
488 0 : struct ifreq *ifr = (struct ifreq *)data;
489 : int error = 0;
490 :
491 0 : switch (cmd) {
492 : case SIOCSIFADDR:
493 0 : tun_init(tp);
494 0 : break;
495 : case SIOCSIFDSTADDR:
496 0 : tun_init(tp);
497 : TUNDEBUG(("%s: destination address set\n", ifp->if_xname));
498 0 : break;
499 : case SIOCSIFMTU:
500 0 : if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > TUNMRU)
501 0 : error = EINVAL;
502 : else
503 0 : ifp->if_mtu = ifr->ifr_mtu;
504 : break;
505 : case SIOCADDMULTI:
506 : case SIOCDELMULTI:
507 : break;
508 : case SIOCSIFFLAGS:
509 : break;
510 : default:
511 0 : if (tp->tun_flags & TUN_LAYER2)
512 0 : error = ether_ioctl(ifp, &tp->arpcom, cmd, data);
513 : else
514 : error = ENOTTY;
515 : }
516 :
517 0 : return (error);
518 : }
519 :
520 : /*
521 : * tun_output - queue packets from higher level ready to put out.
522 : */
523 : int
524 0 : tun_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
525 : struct rtentry *rt)
526 : {
527 0 : struct tun_softc *tp = ifp->if_softc;
528 : int error;
529 : u_int32_t *af;
530 :
531 0 : if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
532 0 : m_freem(m0);
533 0 : return (EHOSTDOWN);
534 : }
535 :
536 : TUNDEBUG(("%s: tun_output\n", ifp->if_xname));
537 :
538 0 : if ((tp->tun_flags & TUN_READY) != TUN_READY) {
539 : TUNDEBUG(("%s: not ready %#x\n", ifp->if_xname,
540 : tp->tun_flags));
541 0 : m_freem(m0);
542 0 : return (EHOSTDOWN);
543 : }
544 :
545 0 : if (tp->tun_flags & TUN_LAYER2)
546 0 : return (ether_output(ifp, m0, dst, rt));
547 :
548 0 : M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
549 0 : if (m0 == NULL)
550 0 : return (ENOBUFS);
551 0 : af = mtod(m0, u_int32_t *);
552 0 : *af = htonl(dst->sa_family);
553 :
554 : #if NBPFILTER > 0
555 0 : if (ifp->if_bpf)
556 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
557 : #endif
558 : #ifdef PIPEX
559 0 : if (pipex_enable && (m0 = pipex_output(m0, dst->sa_family,
560 0 : sizeof(u_int32_t), &tp->pipex_iface)) == NULL) {
561 0 : return (0);
562 : }
563 : #endif
564 :
565 0 : error = if_enqueue(ifp, m0);
566 :
567 0 : if (error) {
568 0 : ifp->if_collisions++;
569 0 : return (error);
570 : }
571 :
572 0 : tun_wakeup(tp);
573 0 : return (0);
574 0 : }
575 :
576 : void
577 0 : tun_wakeup(struct tun_softc *tp)
578 : {
579 0 : if (tp->tun_flags & TUN_RWAIT) {
580 0 : tp->tun_flags &= ~TUN_RWAIT;
581 0 : wakeup((caddr_t)tp);
582 0 : }
583 0 : if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
584 0 : csignal(tp->tun_pgid, SIGIO,
585 0 : tp->tun_siguid, tp->tun_sigeuid);
586 0 : selwakeup(&tp->tun_rsel);
587 0 : }
588 :
589 : /*
590 : * the cdevsw interface is now pretty minimal.
591 : */
592 : int
593 0 : tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
594 : {
595 : struct tun_softc *tp;
596 :
597 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
598 0 : return (ENXIO);
599 0 : return (tun_dev_ioctl(tp, cmd, data, flag, p));
600 0 : }
601 :
602 : int
603 0 : tapioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
604 : {
605 : struct tun_softc *tp;
606 :
607 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
608 0 : return (ENXIO);
609 0 : return (tun_dev_ioctl(tp, cmd, data, flag, p));
610 0 : }
611 :
612 : int
613 0 : tun_dev_ioctl(struct tun_softc *tp, u_long cmd, caddr_t data, int flag,
614 : struct proc *p)
615 : {
616 : struct tuninfo *tunp;
617 :
618 0 : switch (cmd) {
619 : case TUNSIFINFO:
620 0 : tunp = (struct tuninfo *)data;
621 0 : if (tunp->mtu < ETHERMIN || tunp->mtu > TUNMRU)
622 0 : return (EINVAL);
623 0 : tp->tun_if.if_mtu = tunp->mtu;
624 0 : tp->tun_if.if_type = tunp->type;
625 0 : tp->tun_if.if_flags =
626 0 : (tunp->flags & TUN_IFF_FLAGS) |
627 0 : (tp->tun_if.if_flags & ~TUN_IFF_FLAGS);
628 0 : tp->tun_if.if_baudrate = tunp->baudrate;
629 0 : break;
630 : case TUNGIFINFO:
631 0 : tunp = (struct tuninfo *)data;
632 0 : tunp->mtu = tp->tun_if.if_mtu;
633 0 : tunp->type = tp->tun_if.if_type;
634 0 : tunp->flags = tp->tun_if.if_flags;
635 0 : tunp->baudrate = tp->tun_if.if_baudrate;
636 0 : break;
637 : #ifdef TUN_DEBUG
638 : case TUNSDEBUG:
639 : tundebug = *(int *)data;
640 : break;
641 : case TUNGDEBUG:
642 : *(int *)data = tundebug;
643 : break;
644 : #endif
645 : case TUNSIFMODE:
646 0 : switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
647 : case IFF_POINTOPOINT:
648 : case IFF_BROADCAST:
649 0 : tp->tun_if.if_flags &= ~TUN_IFF_FLAGS;
650 0 : tp->tun_if.if_flags |= *(int *)data & TUN_IFF_FLAGS;
651 : break;
652 : default:
653 0 : return (EINVAL);
654 : }
655 0 : break;
656 :
657 : case FIONBIO:
658 0 : if (*(int *)data)
659 0 : tp->tun_flags |= TUN_NBIO;
660 : else
661 0 : tp->tun_flags &= ~TUN_NBIO;
662 : break;
663 : case FIOASYNC:
664 0 : if (*(int *)data)
665 0 : tp->tun_flags |= TUN_ASYNC;
666 : else
667 0 : tp->tun_flags &= ~TUN_ASYNC;
668 : break;
669 : case FIONREAD:
670 0 : *(int *)data = ifq_empty(&tp->tun_if.if_snd) ?
671 0 : 0 : tp->tun_if.if_mtu;
672 0 : break;
673 : case TIOCSPGRP:
674 0 : tp->tun_pgid = *(int *)data;
675 0 : tp->tun_siguid = p->p_ucred->cr_ruid;
676 0 : tp->tun_sigeuid = p->p_ucred->cr_uid;
677 0 : break;
678 : case TIOCGPGRP:
679 0 : *(int *)data = tp->tun_pgid;
680 0 : break;
681 : case SIOCGIFADDR:
682 0 : if (!(tp->tun_flags & TUN_LAYER2))
683 0 : return (EINVAL);
684 0 : bcopy(tp->arpcom.ac_enaddr, data,
685 : sizeof(tp->arpcom.ac_enaddr));
686 0 : break;
687 :
688 : case SIOCSIFADDR:
689 0 : if (!(tp->tun_flags & TUN_LAYER2))
690 0 : return (EINVAL);
691 0 : bcopy(data, tp->arpcom.ac_enaddr,
692 : sizeof(tp->arpcom.ac_enaddr));
693 0 : break;
694 : default:
695 : #ifdef PIPEX
696 0 : if (!(tp->tun_flags & TUN_LAYER2)) {
697 : int ret;
698 0 : ret = pipex_ioctl(&tp->pipex_iface, cmd, data);
699 : return (ret);
700 : }
701 : #endif
702 0 : return (ENOTTY);
703 : }
704 0 : return (0);
705 0 : }
706 :
707 : /*
708 : * The cdevsw read interface - reads a packet at a time, or at
709 : * least as much of a packet as can be read.
710 : */
711 : int
712 0 : tunread(dev_t dev, struct uio *uio, int ioflag)
713 : {
714 : struct tun_softc *tp;
715 :
716 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
717 0 : return (ENXIO);
718 0 : return (tun_dev_read(tp, uio, ioflag));
719 0 : }
720 :
721 : int
722 0 : tapread(dev_t dev, struct uio *uio, int ioflag)
723 : {
724 : struct tun_softc *tp;
725 :
726 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
727 0 : return (ENXIO);
728 0 : return (tun_dev_read(tp, uio, ioflag));
729 0 : }
730 :
731 : int
732 0 : tun_dev_read(struct tun_softc *tp, struct uio *uio, int ioflag)
733 : {
734 0 : struct ifnet *ifp = &tp->tun_if;
735 : struct mbuf *m, *m0;
736 : unsigned int ifidx;
737 : int error = 0;
738 : size_t len;
739 :
740 0 : if ((tp->tun_flags & TUN_READY) != TUN_READY)
741 0 : return (EHOSTDOWN);
742 :
743 0 : ifidx = ifp->if_index;
744 0 : tp->tun_flags &= ~TUN_RWAIT;
745 :
746 0 : do {
747 : struct ifnet *ifp1;
748 : int destroyed;
749 :
750 0 : while ((tp->tun_flags & TUN_READY) != TUN_READY) {
751 0 : if ((error = tsleep((caddr_t)tp,
752 0 : (PZERO + 1)|PCATCH, "tunread", 0)) != 0)
753 0 : return (error);
754 : /* Make sure the interface still exists. */
755 0 : ifp1 = if_get(ifidx);
756 0 : destroyed = (ifp1 == NULL);
757 0 : if_put(ifp1);
758 0 : if (destroyed)
759 0 : return (ENXIO);
760 : }
761 0 : IFQ_DEQUEUE(&ifp->if_snd, m0);
762 0 : if (m0 == NULL) {
763 0 : if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY)
764 0 : return (EWOULDBLOCK);
765 0 : tp->tun_flags |= TUN_RWAIT;
766 0 : if ((error = tsleep((caddr_t)tp,
767 0 : (PZERO + 1)|PCATCH, "tunread", 0)) != 0)
768 0 : return (error);
769 : /* Make sure the interface still exists. */
770 0 : ifp1 = if_get(ifidx);
771 0 : destroyed = (ifp1 == NULL);
772 0 : if_put(ifp1);
773 0 : if (destroyed)
774 0 : return (ENXIO);
775 : }
776 0 : } while (m0 == NULL);
777 :
778 0 : if (tp->tun_flags & TUN_LAYER2) {
779 : #if NBPFILTER > 0
780 0 : if (ifp->if_bpf)
781 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
782 : #endif
783 : }
784 :
785 0 : while (m0 != NULL && uio->uio_resid > 0 && error == 0) {
786 0 : len = ulmin(uio->uio_resid, m0->m_len);
787 0 : if (len != 0)
788 0 : error = uiomove(mtod(m0, caddr_t), len, uio);
789 0 : m = m_free(m0);
790 : m0 = m;
791 : }
792 :
793 0 : if (m0 != NULL) {
794 : TUNDEBUG(("Dropping mbuf\n"));
795 0 : m_freem(m0);
796 0 : }
797 0 : if (error)
798 0 : ifp->if_oerrors++;
799 :
800 0 : return (error);
801 0 : }
802 :
803 : /*
804 : * the cdevsw write interface - an atomic write is a packet - or else!
805 : */
806 : int
807 0 : tunwrite(dev_t dev, struct uio *uio, int ioflag)
808 : {
809 : struct tun_softc *tp;
810 :
811 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
812 0 : return (ENXIO);
813 0 : return (tun_dev_write(tp, uio, ioflag));
814 0 : }
815 :
816 : int
817 0 : tapwrite(dev_t dev, struct uio *uio, int ioflag)
818 : {
819 : struct tun_softc *tp;
820 :
821 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
822 0 : return (ENXIO);
823 0 : return (tun_dev_write(tp, uio, ioflag));
824 0 : }
825 :
826 : int
827 0 : tun_dev_write(struct tun_softc *tp, struct uio *uio, int ioflag)
828 : {
829 : struct ifnet *ifp;
830 : u_int32_t *th;
831 0 : struct mbuf *top, **mp, *m;
832 : int error = 0, tlen;
833 : size_t mlen;
834 :
835 0 : ifp = &tp->tun_if;
836 : TUNDEBUG(("%s: tunwrite\n", ifp->if_xname));
837 :
838 0 : if (uio->uio_resid == 0 || uio->uio_resid > ifp->if_mtu +
839 0 : (tp->tun_flags & TUN_LAYER2 ? ETHER_HDR_LEN : sizeof(*th))) {
840 : TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid));
841 0 : return (EMSGSIZE);
842 : }
843 0 : tlen = uio->uio_resid;
844 :
845 : /* get a header mbuf */
846 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
847 0 : if (m == NULL)
848 0 : return (ENOBUFS);
849 : mlen = MHLEN;
850 0 : if (uio->uio_resid >= MINCLSIZE) {
851 0 : MCLGET(m, M_DONTWAIT);
852 0 : if (!(m->m_flags & M_EXT)) {
853 0 : m_free(m);
854 0 : return (ENOBUFS);
855 : }
856 : mlen = MCLBYTES;
857 0 : }
858 :
859 0 : top = NULL;
860 : mp = ⊤
861 0 : if (tp->tun_flags & TUN_LAYER2) {
862 : /*
863 : * Pad so that IP header is correctly aligned
864 : * this is necessary for all strict aligned architectures.
865 : */
866 0 : mlen -= ETHER_ALIGN;
867 0 : m->m_data += ETHER_ALIGN;
868 0 : }
869 0 : while (error == 0 && uio->uio_resid > 0) {
870 0 : m->m_len = ulmin(mlen, uio->uio_resid);
871 0 : error = uiomove(mtod (m, caddr_t), m->m_len, uio);
872 0 : *mp = m;
873 0 : mp = &m->m_next;
874 0 : if (error == 0 && uio->uio_resid > 0) {
875 0 : MGET(m, M_DONTWAIT, MT_DATA);
876 0 : if (m == NULL) {
877 : error = ENOBUFS;
878 0 : break;
879 : }
880 : mlen = MLEN;
881 0 : if (uio->uio_resid >= MINCLSIZE) {
882 0 : MCLGET(m, M_DONTWAIT);
883 0 : if (!(m->m_flags & M_EXT)) {
884 : error = ENOBUFS;
885 0 : m_free(m);
886 0 : break;
887 : }
888 : mlen = MCLBYTES;
889 0 : }
890 : }
891 : }
892 0 : if (error) {
893 0 : m_freem(top);
894 0 : ifp->if_ierrors++;
895 0 : return (error);
896 : }
897 :
898 0 : top->m_pkthdr.len = tlen;
899 :
900 0 : if (tp->tun_flags & TUN_LAYER2) {
901 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
902 :
903 0 : ml_enqueue(&ml, top);
904 0 : if_input(ifp, &ml);
905 : return (0);
906 0 : }
907 :
908 : #if NBPFILTER > 0
909 0 : if (ifp->if_bpf) {
910 0 : bpf_mtap(ifp->if_bpf, top, BPF_DIRECTION_IN);
911 0 : }
912 : #endif
913 :
914 0 : th = mtod(top, u_int32_t *);
915 : /* strip the tunnel header */
916 0 : top->m_data += sizeof(*th);
917 0 : top->m_len -= sizeof(*th);
918 0 : top->m_pkthdr.len -= sizeof(*th);
919 0 : top->m_pkthdr.ph_rtableid = ifp->if_rdomain;
920 0 : top->m_pkthdr.ph_ifidx = ifp->if_index;
921 :
922 0 : ifp->if_ipackets++;
923 0 : ifp->if_ibytes += top->m_pkthdr.len;
924 :
925 0 : NET_LOCK();
926 :
927 0 : switch (ntohl(*th)) {
928 : case AF_INET:
929 0 : ipv4_input(ifp, top);
930 0 : break;
931 : #ifdef INET6
932 : case AF_INET6:
933 0 : ipv6_input(ifp, top);
934 0 : break;
935 : #endif
936 : default:
937 0 : m_freem(top);
938 : error = EAFNOSUPPORT;
939 0 : break;
940 : }
941 :
942 0 : NET_UNLOCK();
943 :
944 0 : return (error);
945 0 : }
946 :
947 : /*
948 : * tunpoll - the poll interface, this is only useful on reads
949 : * really. The write detect always returns true, write never blocks
950 : * anyway, it either accepts the packet or drops it.
951 : */
952 : int
953 0 : tunpoll(dev_t dev, int events, struct proc *p)
954 : {
955 : struct tun_softc *tp;
956 :
957 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
958 0 : return (POLLERR);
959 0 : return (tun_dev_poll(tp, events, p));
960 0 : }
961 :
962 : int
963 0 : tappoll(dev_t dev, int events, struct proc *p)
964 : {
965 : struct tun_softc *tp;
966 :
967 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
968 0 : return (POLLERR);
969 0 : return (tun_dev_poll(tp, events, p));
970 0 : }
971 :
972 : int
973 0 : tun_dev_poll(struct tun_softc *tp, int events, struct proc *p)
974 : {
975 : int revents;
976 : struct ifnet *ifp;
977 : unsigned int len;
978 :
979 0 : ifp = &tp->tun_if;
980 : revents = 0;
981 : TUNDEBUG(("%s: tunpoll\n", ifp->if_xname));
982 :
983 0 : if (events & (POLLIN | POLLRDNORM)) {
984 0 : len = IFQ_LEN(&ifp->if_snd);
985 0 : if (len > 0) {
986 : TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname, len));
987 : revents |= events & (POLLIN | POLLRDNORM);
988 0 : } else {
989 : TUNDEBUG(("%s: tunpoll waiting\n", ifp->if_xname));
990 0 : selrecord(p, &tp->tun_rsel);
991 : }
992 : }
993 0 : if (events & (POLLOUT | POLLWRNORM))
994 0 : revents |= events & (POLLOUT | POLLWRNORM);
995 0 : return (revents);
996 : }
997 :
998 : /*
999 : * kqueue(2) support.
1000 : *
1001 : * The tun driver uses an array of tun_softc's based on the minor number
1002 : * of the device. kn->kn_hook gets set to the specific tun_softc.
1003 : *
1004 : * filt_tunread() sets kn->kn_data to the iface qsize
1005 : * filt_tunwrite() sets kn->kn_data to the MTU size
1006 : */
1007 : int
1008 0 : tunkqfilter(dev_t dev, struct knote *kn)
1009 : {
1010 : struct tun_softc *tp;
1011 :
1012 0 : if ((tp = tun_lookup(minor(dev))) == NULL)
1013 0 : return (ENXIO);
1014 0 : return (tun_dev_kqfilter(tp, kn));
1015 0 : }
1016 :
1017 : int
1018 0 : tapkqfilter(dev_t dev, struct knote *kn)
1019 : {
1020 : struct tun_softc *tp;
1021 :
1022 0 : if ((tp = tap_lookup(minor(dev))) == NULL)
1023 0 : return (ENXIO);
1024 0 : return (tun_dev_kqfilter(tp, kn));
1025 0 : }
1026 :
1027 : int
1028 0 : tun_dev_kqfilter(struct tun_softc *tp, struct knote *kn)
1029 : {
1030 : int s;
1031 : struct klist *klist;
1032 : struct ifnet *ifp;
1033 :
1034 0 : ifp = &tp->tun_if;
1035 : TUNDEBUG(("%s: tunkqfilter\n", ifp->if_xname));
1036 :
1037 0 : switch (kn->kn_filter) {
1038 : case EVFILT_READ:
1039 0 : klist = &tp->tun_rsel.si_note;
1040 0 : kn->kn_fop = &tunread_filtops;
1041 0 : break;
1042 : case EVFILT_WRITE:
1043 0 : klist = &tp->tun_wsel.si_note;
1044 0 : kn->kn_fop = &tunwrite_filtops;
1045 0 : break;
1046 : default:
1047 0 : return (EINVAL);
1048 : }
1049 :
1050 0 : kn->kn_hook = (caddr_t)tp;
1051 :
1052 0 : s = splhigh();
1053 0 : SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1054 0 : splx(s);
1055 :
1056 0 : return (0);
1057 0 : }
1058 :
1059 : void
1060 0 : filt_tunrdetach(struct knote *kn)
1061 : {
1062 : int s;
1063 : struct tun_softc *tp;
1064 :
1065 0 : tp = (struct tun_softc *)kn->kn_hook;
1066 0 : s = splhigh();
1067 0 : if (!(kn->kn_status & KN_DETACHED))
1068 0 : SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext);
1069 0 : splx(s);
1070 0 : }
1071 :
1072 : int
1073 0 : filt_tunread(struct knote *kn, long hint)
1074 : {
1075 : struct tun_softc *tp;
1076 : struct ifnet *ifp;
1077 : unsigned int len;
1078 :
1079 0 : if (kn->kn_status & KN_DETACHED) {
1080 0 : kn->kn_data = 0;
1081 0 : return (1);
1082 : }
1083 :
1084 0 : tp = (struct tun_softc *)kn->kn_hook;
1085 0 : ifp = &tp->tun_if;
1086 :
1087 0 : len = IFQ_LEN(&ifp->if_snd);
1088 0 : if (len > 0) {
1089 0 : kn->kn_data = len;
1090 :
1091 : TUNDEBUG(("%s: tunkqread q=%d\n", ifp->if_xname,
1092 : IFQ_LEN(&ifp->if_snd)));
1093 0 : return (1);
1094 : }
1095 : TUNDEBUG(("%s: tunkqread waiting\n", ifp->if_xname));
1096 0 : return (0);
1097 0 : }
1098 :
1099 : void
1100 0 : filt_tunwdetach(struct knote *kn)
1101 : {
1102 : int s;
1103 : struct tun_softc *tp;
1104 :
1105 0 : tp = (struct tun_softc *)kn->kn_hook;
1106 0 : s = splhigh();
1107 0 : if (!(kn->kn_status & KN_DETACHED))
1108 0 : SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext);
1109 0 : splx(s);
1110 0 : }
1111 :
1112 : int
1113 0 : filt_tunwrite(struct knote *kn, long hint)
1114 : {
1115 : struct tun_softc *tp;
1116 : struct ifnet *ifp;
1117 :
1118 0 : if (kn->kn_status & KN_DETACHED) {
1119 0 : kn->kn_data = 0;
1120 0 : return (1);
1121 : }
1122 :
1123 0 : tp = (struct tun_softc *)kn->kn_hook;
1124 0 : ifp = &tp->tun_if;
1125 :
1126 0 : kn->kn_data = ifp->if_mtu;
1127 :
1128 0 : return (1);
1129 0 : }
1130 :
1131 : void
1132 0 : tun_start(struct ifnet *ifp)
1133 : {
1134 0 : struct tun_softc *tp = ifp->if_softc;
1135 :
1136 0 : splassert(IPL_NET);
1137 :
1138 0 : if (IFQ_LEN(&ifp->if_snd))
1139 0 : tun_wakeup(tp);
1140 0 : }
1141 :
1142 : void
1143 0 : tun_link_state(struct tun_softc *tp)
1144 : {
1145 0 : struct ifnet *ifp = &tp->tun_if;
1146 : int link_state = LINK_STATE_DOWN;
1147 :
1148 0 : if (tp->tun_flags & TUN_OPEN) {
1149 0 : if (tp->tun_flags & TUN_LAYER2)
1150 0 : link_state = LINK_STATE_FULL_DUPLEX;
1151 : else
1152 : link_state = LINK_STATE_UP;
1153 : }
1154 0 : if (ifp->if_link_state != link_state) {
1155 0 : ifp->if_link_state = link_state;
1156 0 : if_link_state_change(ifp);
1157 0 : }
1158 0 : }
|