Deleted Added
full compact
if_tun.c (347376) if_tun.c (347378)
1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5 * Nottingham University 1987.
6 *
7 * This source may be freely distributed, however I would be interested
8 * in any changes that are made.
9 *
10 * This driver takes packets off the IP i/f and hands them up to a
11 * user process to have its wicked way with. This driver has it's
12 * roots in a similar driver written by Phil Cockcroft (formerly) at
13 * UCL. This driver is based much more on read/write/poll mode of
14 * operation though.
15 *
1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5 * Nottingham University 1987.
6 *
7 * This source may be freely distributed, however I would be interested
8 * in any changes that are made.
9 *
10 * This driver takes packets off the IP i/f and hands them up to a
11 * user process to have its wicked way with. This driver has it's
12 * roots in a similar driver written by Phil Cockcroft (formerly) at
13 * UCL. This driver is based much more on read/write/poll mode of
14 * operation though.
15 *
16 * $FreeBSD: stable/11/sys/net/if_tun.c 347376 2019-05-09 01:16:03Z kevans $
16 * $FreeBSD: stable/11/sys/net/if_tun.c 347378 2019-05-09 03:51:34Z kevans $
17 */
18
19#include "opt_inet.h"
20#include "opt_inet6.h"
21
22#include <sys/param.h>
17 */
18
19#include "opt_inet.h"
20#include "opt_inet6.h"
21
22#include <sys/param.h>
23#include <sys/lock.h>
23#include <sys/priv.h>
24#include <sys/proc.h>
25#include <sys/systm.h>
26#include <sys/jail.h>
27#include <sys/mbuf.h>
28#include <sys/module.h>
29#include <sys/socket.h>
30#include <sys/fcntl.h>
31#include <sys/filio.h>
32#include <sys/sockio.h>
24#include <sys/priv.h>
25#include <sys/proc.h>
26#include <sys/systm.h>
27#include <sys/jail.h>
28#include <sys/mbuf.h>
29#include <sys/module.h>
30#include <sys/socket.h>
31#include <sys/fcntl.h>
32#include <sys/filio.h>
33#include <sys/sockio.h>
34#include <sys/sx.h>
33#include <sys/ttycom.h>
34#include <sys/poll.h>
35#include <sys/selinfo.h>
36#include <sys/signalvar.h>
37#include <sys/filedesc.h>
38#include <sys/kernel.h>
39#include <sys/sysctl.h>
40#include <sys/conf.h>

--- 33 unchanged lines hidden (view full) ---

74#define TUN_INITED 0x0002
75#define TUN_RCOLL 0x0004
76#define TUN_IASET 0x0008
77#define TUN_DSTADDR 0x0010
78#define TUN_LMODE 0x0020
79#define TUN_RWAIT 0x0040
80#define TUN_ASYNC 0x0080
81#define TUN_IFHEAD 0x0100
35#include <sys/ttycom.h>
36#include <sys/poll.h>
37#include <sys/selinfo.h>
38#include <sys/signalvar.h>
39#include <sys/filedesc.h>
40#include <sys/kernel.h>
41#include <sys/sysctl.h>
42#include <sys/conf.h>

--- 33 unchanged lines hidden (view full) ---

76#define TUN_INITED 0x0002
77#define TUN_RCOLL 0x0004
78#define TUN_IASET 0x0008
79#define TUN_DSTADDR 0x0010
80#define TUN_LMODE 0x0020
81#define TUN_RWAIT 0x0040
82#define TUN_ASYNC 0x0080
83#define TUN_IFHEAD 0x0100
84#define TUN_DYING 0x0200
82
83#define TUN_READY (TUN_OPEN | TUN_INITED)
84
85
86#define TUN_READY (TUN_OPEN | TUN_INITED)
87
85 /*
86 * XXXRW: tun_pid is used to exclusively lock /dev/tun. Is this
87 * actually needed? Can we just return EBUSY if already open?
88 * Problem is that this involved inherent races when a tun device
89 * is handed off from one process to another, as opposed to just
90 * being slightly stale informationally.
91 */
92 pid_t tun_pid; /* owning pid */
93 struct ifnet *tun_ifp; /* the interface */
94 struct sigio *tun_sigio; /* information for async I/O */
95 struct selinfo tun_rsel; /* read select */
96 struct mtx tun_mtx; /* protect mutable softc fields */
97 struct cv tun_cv; /* protect against ref'd dev destroy */
98};
99#define TUN2IFP(sc) ((sc)->tun_ifp)

--- 10 unchanged lines hidden (view full) ---

110static const char tunname[] = "tun";
111static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
112static int tundebug = 0;
113static int tundclone = 1;
114static struct clonedevs *tunclones;
115static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
116SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
117
88 pid_t tun_pid; /* owning pid */
89 struct ifnet *tun_ifp; /* the interface */
90 struct sigio *tun_sigio; /* information for async I/O */
91 struct selinfo tun_rsel; /* read select */
92 struct mtx tun_mtx; /* protect mutable softc fields */
93 struct cv tun_cv; /* protect against ref'd dev destroy */
94};
95#define TUN2IFP(sc) ((sc)->tun_ifp)

--- 10 unchanged lines hidden (view full) ---

106static const char tunname[] = "tun";
107static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
108static int tundebug = 0;
109static int tundclone = 1;
110static struct clonedevs *tunclones;
111static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
112SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
113
114static struct sx tun_ioctl_sx;
115SX_SYSINIT(tun_ioctl_sx, &tun_ioctl_sx, "tun_ioctl");
116
118SYSCTL_DECL(_net_link);
119static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
120 "IP tunnel software network interface.");
121SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tundclone, 0,
122 "Enable legacy devfs interface creation.");
123
124static void tunclone(void *arg, struct ucred *cred, char *name,
125 int namelen, struct cdev **dev);

--- 141 unchanged lines hidden (view full) ---

267}
268
269static void
270tun_destroy(struct tun_softc *tp)
271{
272 struct cdev *dev;
273
274 mtx_lock(&tp->tun_mtx);
117SYSCTL_DECL(_net_link);
118static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
119 "IP tunnel software network interface.");
120SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tundclone, 0,
121 "Enable legacy devfs interface creation.");
122
123static void tunclone(void *arg, struct ucred *cred, char *name,
124 int namelen, struct cdev **dev);

--- 141 unchanged lines hidden (view full) ---

266}
267
268static void
269tun_destroy(struct tun_softc *tp)
270{
271 struct cdev *dev;
272
273 mtx_lock(&tp->tun_mtx);
274 tp->tun_flags |= TUN_DYING;
275 if ((tp->tun_flags & TUN_OPEN) != 0)
276 cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
277 else
278 mtx_unlock(&tp->tun_mtx);
279
280 CURVNET_SET(TUN2IFP(tp)->if_vnet);
275 if ((tp->tun_flags & TUN_OPEN) != 0)
276 cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
277 else
278 mtx_unlock(&tp->tun_mtx);
279
280 CURVNET_SET(TUN2IFP(tp)->if_vnet);
281 sx_xlock(&tun_ioctl_sx);
282 TUN2IFP(tp)->if_softc = NULL;
283 sx_xunlock(&tun_ioctl_sx);
284
281 dev = tp->tun_dev;
282 bpfdetach(TUN2IFP(tp));
283 if_detach(TUN2IFP(tp));
284 free_unr(tun_unrhdr, TUN2IFP(tp)->if_dunit);
285 if_free(TUN2IFP(tp));
286 destroy_dev(dev);
287 seldrain(&tp->tun_rsel);
288 knlist_clear(&tp->tun_rsel.si_note, 0);

--- 170 unchanged lines hidden (view full) ---

459 * synchronization.
460 */
461 tp = dev->si_drv1;
462 if (!tp) {
463 tuncreate(tunname, dev);
464 tp = dev->si_drv1;
465 }
466
285 dev = tp->tun_dev;
286 bpfdetach(TUN2IFP(tp));
287 if_detach(TUN2IFP(tp));
288 free_unr(tun_unrhdr, TUN2IFP(tp)->if_dunit);
289 if_free(TUN2IFP(tp));
290 destroy_dev(dev);
291 seldrain(&tp->tun_rsel);
292 knlist_clear(&tp->tun_rsel.si_note, 0);

--- 170 unchanged lines hidden (view full) ---

463 * synchronization.
464 */
465 tp = dev->si_drv1;
466 if (!tp) {
467 tuncreate(tunname, dev);
468 tp = dev->si_drv1;
469 }
470
467 /*
468 * XXXRW: This use of tun_pid is subject to error due to the
469 * fact that a reference to the tunnel can live beyond the
470 * death of the process that created it. Can we replace this
471 * with a simple busy flag?
472 */
473 mtx_lock(&tp->tun_mtx);
471 mtx_lock(&tp->tun_mtx);
474 if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
472 if ((tp->tun_flags & (TUN_OPEN | TUN_DYING)) != 0) {
475 mtx_unlock(&tp->tun_mtx);
476 return (EBUSY);
477 }
473 mtx_unlock(&tp->tun_mtx);
474 return (EBUSY);
475 }
478 tp->tun_pid = td->td_proc->p_pid;
479
476
477 tp->tun_pid = td->td_proc->p_pid;
480 tp->tun_flags |= TUN_OPEN;
481 ifp = TUN2IFP(tp);
482 if_link_state_change(ifp, LINK_STATE_UP);
483 TUNDEBUG(ifp, "open\n");
484 mtx_unlock(&tp->tun_mtx);
485
486 return (0);
487}

--- 7 unchanged lines hidden (view full) ---

495{
496 struct tun_softc *tp;
497 struct ifnet *ifp;
498
499 tp = dev->si_drv1;
500 ifp = TUN2IFP(tp);
501
502 mtx_lock(&tp->tun_mtx);
478 tp->tun_flags |= TUN_OPEN;
479 ifp = TUN2IFP(tp);
480 if_link_state_change(ifp, LINK_STATE_UP);
481 TUNDEBUG(ifp, "open\n");
482 mtx_unlock(&tp->tun_mtx);
483
484 return (0);
485}

--- 7 unchanged lines hidden (view full) ---

493{
494 struct tun_softc *tp;
495 struct ifnet *ifp;
496
497 tp = dev->si_drv1;
498 ifp = TUN2IFP(tp);
499
500 mtx_lock(&tp->tun_mtx);
503 tp->tun_flags &= ~TUN_OPEN;
504 tp->tun_pid = 0;
501 /*
502 * Simply close the device if this isn't the controlling process. This
503 * may happen if, for instance, the tunnel has been handed off to
504 * another process. The original controller should be able to close it
505 * without putting us into an inconsistent state.
506 */
507 if (td->td_proc->p_pid != tp->tun_pid) {
508 mtx_unlock(&tp->tun_mtx);
509 return (0);
510 }
505
506 /*
507 * junk all pending output
508 */
509 CURVNET_SET(ifp->if_vnet);
510 IFQ_PURGE(&ifp->if_snd);
511
512 if (ifp->if_flags & IFF_UP) {

--- 22 unchanged lines hidden (view full) ---

535 }
536 if_link_state_change(ifp, LINK_STATE_DOWN);
537 CURVNET_RESTORE();
538
539 funsetown(&tp->tun_sigio);
540 selwakeuppri(&tp->tun_rsel, PZERO + 1);
541 KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
542 TUNDEBUG (ifp, "closed\n");
511
512 /*
513 * junk all pending output
514 */
515 CURVNET_SET(ifp->if_vnet);
516 IFQ_PURGE(&ifp->if_snd);
517
518 if (ifp->if_flags & IFF_UP) {

--- 22 unchanged lines hidden (view full) ---

541 }
542 if_link_state_change(ifp, LINK_STATE_DOWN);
543 CURVNET_RESTORE();
544
545 funsetown(&tp->tun_sigio);
546 selwakeuppri(&tp->tun_rsel, PZERO + 1);
547 KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
548 TUNDEBUG (ifp, "closed\n");
549 tp->tun_flags &= ~TUN_OPEN;
550 tp->tun_pid = 0;
543
544 cv_broadcast(&tp->tun_cv);
545 mtx_unlock(&tp->tun_mtx);
546 return (0);
547}
548
549static void
550tuninit(struct ifnet *ifp)

--- 32 unchanged lines hidden (view full) ---

583
584/*
585 * Process an ioctl request.
586 */
587static int
588tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
589{
590 struct ifreq *ifr = (struct ifreq *)data;
551
552 cv_broadcast(&tp->tun_cv);
553 mtx_unlock(&tp->tun_mtx);
554 return (0);
555}
556
557static void
558tuninit(struct ifnet *ifp)

--- 32 unchanged lines hidden (view full) ---

591
592/*
593 * Process an ioctl request.
594 */
595static int
596tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
597{
598 struct ifreq *ifr = (struct ifreq *)data;
591 struct tun_softc *tp = ifp->if_softc;
599 struct tun_softc *tp;
592 struct ifstat *ifs;
593 int error = 0;
594
600 struct ifstat *ifs;
601 int error = 0;
602
603 sx_xlock(&tun_ioctl_sx);
604 tp = ifp->if_softc;
605 if (tp == NULL) {
606 error = ENXIO;
607 goto bad;
608 }
595 switch(cmd) {
596 case SIOCGIFSTATUS:
597 ifs = (struct ifstat *)data;
598 mtx_lock(&tp->tun_mtx);
599 if (tp->tun_pid)
600 snprintf(ifs->ascii, sizeof(ifs->ascii),
601 "\tOpened by PID %d\n", tp->tun_pid);
602 else

--- 10 unchanged lines hidden (view full) ---

613 break;
614 case SIOCSIFFLAGS:
615 case SIOCADDMULTI:
616 case SIOCDELMULTI:
617 break;
618 default:
619 error = EINVAL;
620 }
609 switch(cmd) {
610 case SIOCGIFSTATUS:
611 ifs = (struct ifstat *)data;
612 mtx_lock(&tp->tun_mtx);
613 if (tp->tun_pid)
614 snprintf(ifs->ascii, sizeof(ifs->ascii),
615 "\tOpened by PID %d\n", tp->tun_pid);
616 else

--- 10 unchanged lines hidden (view full) ---

627 break;
628 case SIOCSIFFLAGS:
629 case SIOCADDMULTI:
630 case SIOCDELMULTI:
631 break;
632 default:
633 error = EINVAL;
634 }
635bad:
636 sx_xunlock(&tun_ioctl_sx);
621 return (error);
622}
623
624/*
625 * tunoutput - queue packets from higher level ready to put out.
626 */
627static int
628tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,

--- 468 unchanged lines hidden ---
637 return (error);
638}
639
640/*
641 * tunoutput - queue packets from higher level ready to put out.
642 */
643static int
644tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,

--- 468 unchanged lines hidden ---