Deleted Added
full compact
if_tun.c (241394) if_tun.c (241610)
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: head/sys/net/if_tun.c 241394 2012-10-10 08:36:38Z kevlo $
16 * $FreeBSD: head/sys/net/if_tun.c 241610 2012-10-16 13:37:54Z glebius $
17 */
18
19#include "opt_atalk.h"
20#include "opt_inet.h"
21#include "opt_inet6.h"
22#include "opt_ipx.h"
23
24#include <sys/param.h>

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

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)
100
101#define TUNDEBUG if (tundebug) if_printf
17 */
18
19#include "opt_atalk.h"
20#include "opt_inet.h"
21#include "opt_inet6.h"
22#include "opt_ipx.h"
23
24#include <sys/param.h>

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

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)
100
101#define TUNDEBUG if (tundebug) if_printf
102#define TUNNAME "tun"
103
104/*
105 * All mutable global variables in if_tun are locked using tunmtx, with
106 * the exception of tundebug, which is used unlocked, and tunclones,
107 * which is static after setup.
108 */
109static struct mtx tunmtx;
102
103/*
104 * All mutable global variables in if_tun are locked using tunmtx, with
105 * the exception of tundebug, which is used unlocked, and tunclones,
106 * which is static after setup.
107 */
108static struct mtx tunmtx;
110static MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface");
109static const char tunname[] = "tun";
110static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
111static int tundebug = 0;
112static int tundclone = 1;
113static struct clonedevs *tunclones;
114static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
115SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
116
117SYSCTL_DECL(_net_link);
118static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,

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

129static void tuninit(struct ifnet *);
130static int tunmodevent(module_t, int, void *);
131static int tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
132 struct route *ro);
133static void tunstart(struct ifnet *);
134
135static int tun_clone_create(struct if_clone *, int, caddr_t);
136static void tun_clone_destroy(struct ifnet *);
111static int tundebug = 0;
112static int tundclone = 1;
113static struct clonedevs *tunclones;
114static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
115SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
116
117SYSCTL_DECL(_net_link);
118static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,

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

129static void tuninit(struct ifnet *);
130static int tunmodevent(module_t, int, void *);
131static int tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
132 struct route *ro);
133static void tunstart(struct ifnet *);
134
135static int tun_clone_create(struct if_clone *, int, caddr_t);
136static void tun_clone_destroy(struct ifnet *);
137static struct if_clone *tun_cloner;
137
138
138IFC_SIMPLE_DECLARE(tun, 0);
139
140static d_open_t tunopen;
141static d_close_t tunclose;
142static d_read_t tunread;
143static d_write_t tunwrite;
144static d_ioctl_t tunioctl;
145static d_poll_t tunpoll;
146static d_kqfilter_t tunkqfilter;
147

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

168 .d_flags = D_NEEDMINOR,
169 .d_open = tunopen,
170 .d_close = tunclose,
171 .d_read = tunread,
172 .d_write = tunwrite,
173 .d_ioctl = tunioctl,
174 .d_poll = tunpoll,
175 .d_kqfilter = tunkqfilter,
139static d_open_t tunopen;
140static d_close_t tunclose;
141static d_read_t tunread;
142static d_write_t tunwrite;
143static d_ioctl_t tunioctl;
144static d_poll_t tunpoll;
145static d_kqfilter_t tunkqfilter;
146

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

167 .d_flags = D_NEEDMINOR,
168 .d_open = tunopen,
169 .d_close = tunclose,
170 .d_read = tunread,
171 .d_write = tunwrite,
172 .d_ioctl = tunioctl,
173 .d_poll = tunpoll,
174 .d_kqfilter = tunkqfilter,
176 .d_name = TUNNAME,
175 .d_name = tunname,
177};
178
179static int
180tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
181{
182 struct cdev *dev;
183 int i;
184
185 /* find any existing device, or allocate new unit number */
186 i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
187 if (i) {
188 /* No preexisting struct cdev *, create one */
189 dev = make_dev(&tun_cdevsw, unit,
176};
177
178static int
179tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
180{
181 struct cdev *dev;
182 int i;
183
184 /* find any existing device, or allocate new unit number */
185 i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
186 if (i) {
187 /* No preexisting struct cdev *, create one */
188 dev = make_dev(&tun_cdevsw, unit,
190 UID_UUCP, GID_DIALER, 0600, "%s%d", ifc->ifc_name, unit);
189 UID_UUCP, GID_DIALER, 0600, "%s%d", tunname, unit);
191 }
190 }
192 tuncreate(ifc->ifc_name, dev);
191 tuncreate(tunname, dev);
193
194 return (0);
195}
196
197static void
198tunclone(void *arg, struct ucred *cred, char *name, int namelen,
199 struct cdev **dev)
200{

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

206
207 /*
208 * If tun cloning is enabled, only the superuser can create an
209 * interface.
210 */
211 if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
212 return;
213
192
193 return (0);
194}
195
196static void
197tunclone(void *arg, struct ucred *cred, char *name, int namelen,
198 struct cdev **dev)
199{

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

205
206 /*
207 * If tun cloning is enabled, only the superuser can create an
208 * interface.
209 */
210 if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
211 return;
212
214 if (strcmp(name, TUNNAME) == 0) {
213 if (strcmp(name, tunname) == 0) {
215 u = -1;
214 u = -1;
216 } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
215 } else if (dev_stdclone(name, NULL, tunname, &u) != 1)
217 return; /* Don't recognise the name */
218 if (u != -1 && u > IF_MAXUNIT)
219 return; /* Unit number too high */
220
221 if (u == -1)
222 append_unit = 1;
223 else
224 append_unit = 0;

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

285
286 switch (type) {
287 case MOD_LOAD:
288 mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
289 clone_setup(&tunclones);
290 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
291 if (tag == NULL)
292 return (ENOMEM);
216 return; /* Don't recognise the name */
217 if (u != -1 && u > IF_MAXUNIT)
218 return; /* Unit number too high */
219
220 if (u == -1)
221 append_unit = 1;
222 else
223 append_unit = 0;

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

284
285 switch (type) {
286 case MOD_LOAD:
287 mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
288 clone_setup(&tunclones);
289 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
290 if (tag == NULL)
291 return (ENOMEM);
293 if_clone_attach(&tun_cloner);
292 tun_cloner = if_clone_simple(tunname, tun_clone_create,
293 tun_clone_destroy, 0);
294 break;
295 case MOD_UNLOAD:
294 break;
295 case MOD_UNLOAD:
296 if_clone_detach(&tun_cloner);
296 if_clone_detach(tun_cloner);
297 EVENTHANDLER_DEREGISTER(dev_clone, tag);
298 drain_dev_clone_events();
299
300 mtx_lock(&tunmtx);
301 while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
302 TAILQ_REMOVE(&tunhead, tp, tun_list);
303 mtx_unlock(&tunmtx);
304 tun_destroy(tp);

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

403 struct tun_softc *tp;
404
405 /*
406 * XXXRW: Non-atomic test and set of dev->si_drv1 requires
407 * synchronization.
408 */
409 tp = dev->si_drv1;
410 if (!tp) {
297 EVENTHANDLER_DEREGISTER(dev_clone, tag);
298 drain_dev_clone_events();
299
300 mtx_lock(&tunmtx);
301 while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
302 TAILQ_REMOVE(&tunhead, tp, tun_list);
303 mtx_unlock(&tunmtx);
304 tun_destroy(tp);

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

403 struct tun_softc *tp;
404
405 /*
406 * XXXRW: Non-atomic test and set of dev->si_drv1 requires
407 * synchronization.
408 */
409 tp = dev->si_drv1;
410 if (!tp) {
411 tuncreate(TUNNAME, dev);
411 tuncreate(tunname, dev);
412 tp = dev->si_drv1;
413 }
414
415 /*
416 * XXXRW: This use of tun_pid is subject to error due to the
417 * fact that a reference to the tunnel can live beyond the
418 * death of the process that created it. Can we replace this
419 * with a simple busy flag?

--- 632 unchanged lines hidden ---
412 tp = dev->si_drv1;
413 }
414
415 /*
416 * XXXRW: This use of tun_pid is subject to error due to the
417 * fact that a reference to the tunnel can live beyond the
418 * death of the process that created it. Can we replace this
419 * with a simple busy flag?

--- 632 unchanged lines hidden ---