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 --- |