Deleted Added
sdiff udiff text old ( 166443 ) new ( 166497 )
full compact
1/*-
2 * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

26 * BASED ON:
27 * -------------------------------------------------------------------------
28 *
29 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
30 * Nottingham University 1987.
31 */
32
33/*
34 * $FreeBSD: head/sys/net/if_tap.c 166443 2007-02-03 02:57:45Z bms $
35 * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
36 */
37
38#include "opt_compat.h"
39#include "opt_inet.h"
40
41#include <sys/param.h>
42#include <sys/conf.h>

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

57#include <sys/systm.h>
58#include <sys/ttycom.h>
59#include <sys/uio.h>
60#include <sys/queue.h>
61
62#include <net/bpf.h>
63#include <net/ethernet.h>
64#include <net/if.h>
65#include <net/if_dl.h>
66#include <net/route.h>
67#include <net/if_types.h>
68
69#include <netinet/in.h>
70
71#include <net/if_tapvar.h>
72#include <net/if_tap.h>

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

88 struct cdev **);
89static void tapcreate(struct cdev *);
90
91/* network interface */
92static void tapifstart(struct ifnet *);
93static int tapifioctl(struct ifnet *, u_long, caddr_t);
94static void tapifinit(void *);
95
96/* character device */
97static d_open_t tapopen;
98static d_close_t tapclose;
99static d_read_t tapread;
100static d_write_t tapwrite;
101static d_ioctl_t tapioctl;
102static d_poll_t tappoll;
103static d_kqfilter_t tapkqfilter;

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

137/*
138 * All global variables in if_tap.c are locked with tapmtx, with the
139 * exception of tapdebug, which is accessed unlocked; tapclones is
140 * static at runtime.
141 */
142static struct mtx tapmtx;
143static int tapdebug = 0; /* debug flag */
144static int tapuopen = 0; /* allow user open() */
145static SLIST_HEAD(, tap_softc) taphead; /* first device */
146static struct clonedevs *tapclones;
147
148MALLOC_DECLARE(M_TAP);
149MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface");
150SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
151
152SYSCTL_DECL(_net_link);
153SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
154 "Ethernet tunnel software network interface");
155SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0,
156 "Allow user to open /dev/tap (based on node permissions)");
157SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, "");
158
159DEV_MODULE(if_tap, tapmodevent, NULL);
160
161/*
162 * tapmodevent
163 *
164 * module event handler
165 */
166static int
167tapmodevent(module_t mod, int type, void *data)
168{
169 static eventhandler_tag eh_tag = NULL;
170 struct tap_softc *tp = NULL;
171 struct ifnet *ifp = NULL;
172 int s;
173
174 switch (type) {
175 case MOD_LOAD:
176
177 /* intitialize device */
178
179 mtx_init(&tapmtx, "tapmtx", NULL, MTX_DEF);
180 SLIST_INIT(&taphead);
181
182 clone_setup(&tapclones);
183 eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000);
184 if (eh_tag == NULL) {
185 clone_cleanup(&tapclones);
186 mtx_destroy(&tapmtx);
187 return (ENOMEM);
188 }
189 return (0);
190
191 case MOD_UNLOAD:
192 /*
193 * The EBUSY algorithm here can't quite atomically
194 * guarantee that this is race-free since we have to
195 * release the tap mtx to deregister the clone handler.
196 */

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

202 mtx_unlock(&tapmtx);
203 return (EBUSY);
204 }
205 mtx_unlock(&tp->tap_mtx);
206 }
207 mtx_unlock(&tapmtx);
208
209 EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
210
211 mtx_lock(&tapmtx);
212 while ((tp = SLIST_FIRST(&taphead)) != NULL) {
213 SLIST_REMOVE_HEAD(&taphead, tap_next);
214 mtx_unlock(&tapmtx);
215
216 ifp = tp->tap_ifp;
217
218 TAPDEBUG("detaching %s\n", ifp->if_xname);
219
220 /* Unlocked read. */
221 KASSERT(!(tp->tap_flags & TAP_OPEN),
222 ("%s flags is out of sync", ifp->if_xname));
223
224 knlist_destroy(&tp->tap_rsel.si_note);
225 destroy_dev(tp->tap_dev);
226 s = splimp();
227 ether_ifdetach(ifp);
228 if_free_type(ifp, IFT_ETHER);
229 splx(s);
230
231 mtx_destroy(&tp->tap_mtx);
232 free(tp, M_TAP);
233 mtx_lock(&tapmtx);
234 }
235 mtx_unlock(&tapmtx);
236 clone_cleanup(&tapclones);
237
238 mtx_destroy(&tapmtx);
239
240 break;

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

250/*
251 * DEVFS handler
252 *
253 * We need to support two kind of devices - tap and vmnet
254 */
255static void
256tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev)
257{
258 int extra;
259 int i, unit;
260 char *device_name = name;
261
262 if (*dev != NULL)
263 return;
264
265 device_name = TAP;
266 extra = 0;
267 if (strcmp(name, TAP) == 0) {
268 unit = -1;
269 } else if (strcmp(name, VMNET) == 0) {
270 device_name = VMNET;
271 extra = VMNET_DEV_MASK;
272 unit = -1;
273 } else if (dev_stdclone(name, NULL, device_name, &unit) != 1) {
274 device_name = VMNET;
275 extra = VMNET_DEV_MASK;
276 if (dev_stdclone(name, NULL, device_name, &unit) != 1)
277 return;
278 }
279
280 /* find any existing device, or allocate new unit number */
281 i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra);
282 if (i) {
283 *dev = make_dev(&tap_cdevsw, unit2minor(unit | extra),
284 UID_ROOT, GID_WHEEL, 0600, "%s%d", device_name, unit);
285 if (*dev != NULL) {
286 dev_ref(*dev);
287 (*dev)->si_flags |= SI_CHEAPCLONE;
288 }
289 }
290} /* tapclone */
291
292
293/*
294 * tapcreate
295 *
296 * to create interface
297 */

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

380 error = priv_check(td, PRIV_NET_TAP);
381 if (error)
382 return (error);
383 }
384
385 if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT)
386 return (ENXIO);
387
388 /*
389 * XXXRW: Non-atomic test-and-set of si_drv1. Currently protected
390 * by Giant, but the race actually exists under memory pressure as
391 * well even when running with Giant, as malloc() may sleep.
392 */
393 tp = dev->si_drv1;
394 if (tp == NULL) {
395 tapcreate(dev);
396 tp = dev->si_drv1;
397 }
398
399 mtx_lock(&tp->tap_mtx);
400 if (tp->tap_flags & TAP_OPEN) {
401 mtx_unlock(&tp->tap_mtx);
402 return (EBUSY);
403 }
404
405 bcopy(IF_LLADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr));

--- 601 unchanged lines hidden ---