xref: /netbsd-src/sys/net/if_tun.c (revision 5f7096188587a2c7c95fa3c69b78e1ec9c7923d0)
1 /*
2  * Copyright (c) 1988, Julian Onions.
3  *
4  * This source may be freely distributed, however I would be interested
5  * in any changes that are made.
6  *
7  *  if_tun.c - tunnel interface module & driver
8  *
9  * $Id: if_tun.c,v 1.7 1993/11/14 20:33:26 deraadt Exp $
10  */
11 
12 #include "tun.h"
13 #if NTUN > 0
14 
15 /*
16  * Tunnel driver.
17  *
18  * This driver takes packets off the IP i/f and hands them up to a
19  * user process to have it's wicked way with. This driver has it's
20  * roots in a similar driver written by Phil Cockcroft (formerly) at
21  * UCL. This driver is based much more on read/write/select mode of
22  * operation though.
23  *
24  * Julian Onions <jpo@cs.nott.ac.uk>
25  * Nottingham University 1987.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/mbuf.h>
31 #include <sys/buf.h>
32 #include <sys/protosw.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <sys/errno.h>
36 #include <sys/syslog.h>
37 #include <sys/select.h>
38 
39 #include <net/if.h>
40 #include <net/if_tun.h>
41 #include <net/netisr.h>
42 #include <net/route.h>
43 
44 #ifdef INET
45 #include <netinet/in.h>
46 #include <netinet/in_systm.h>
47 #include <netinet/in_var.h>
48 #include <netinet/ip.h>
49 #include <netinet/if_ether.h>
50 #endif
51 
52 #ifdef NS
53 #include <netns/ns.h>
54 #include <netns/ns_if.h>
55 #endif
56 
57 #define TUNDEBUG	if (tundebug) printf
58 int	tundebug = 0;
59 
60 struct tun_softc tunctl[NTUN];
61 extern int ifqmaxlen;
62 
63 int	tunoutput __P((dev_t, int, int, struct proc *));
64 int	tunclose __P((dev_t, int));
65 int	tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *));
66 int	tunread __P((dev_t, struct uio *));
67 int	tunwrite __P((dev_t, struct uio *));
68 int	tuncioctl __P((dev_t, int, caddr_t, data);
69 int	tunioctl __P((struct ifnet *, int, caddr_t, int));
70 int	tunselect __P((dev_t, int);
71 
72 static int tunattach __P((int));
73 static int tuninit __P((int));
74 
75 /*
76  * tunnel open - must be superuser & the device must be
77  * configured in
78  */
79 int
80 tunopen(dev, flag, mode, p)
81 	dev_t	dev;
82 	int	flag, mode;
83 	struct proc *p;
84 {
85 	struct ifnet	*ifp;
86 	struct tunctl	*tp;
87 	register int	unit, error;
88 
89 	if (error = suser(p->p_ucred, &p->p_acflag))
90 		return (error);
91 
92 	if ((unit = minor(dev)) >= NTUN)
93 		return (ENXIO);
94 	tp = &tunctl[unit];
95 	if (tp->tun_flags & TUN_OPEN)
96 		return ENXIO;
97 	if ((tp->tun_flags & TUN_INITED) == 0) {
98 		tp->tun_flags = TUN_INITED;
99 		tunattach(unit);
100 	}
101 	ifp = &tp->tun_if;
102 	tp->tun_flags |= TUN_OPEN;
103 	TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
104 	return (0);
105 }
106 
107 /*
108  * tunclose - close the device - mark i/f down & delete
109  * routing info
110  */
111 int
112 tunclose(dev, flag)
113 	dev_t	dev;
114 	int	flag;
115 {
116 	struct tunctl	*tp = &tunctl[unit];
117 	struct ifnet	*ifp = &tp->tun_if;
118 	struct mbuf	*m;
119 	register int	unit = minor(dev), s;
120 
121 	tp->tun_flags &= TUN_INITED;
122 
123 	/*
124 	 * junk all pending output
125 	 */
126 	do {
127 		s = splimp();
128 		IF_DEQUEUE(&ifp->if_snd, m);
129 		splx(s);
130 		if (m)
131 			m_freem(m);
132 	} while (m);
133 
134 	if (ifp->if_flags & IFF_UP) {
135 		s = splimp();
136 		if_down(ifp);
137 		if (ifp->if_flags & IFF_RUNNING)
138 			rtinit(ifp->if_addrlist, (int)SIOCDELRT, RTF_HOST);
139 		splx(s);
140 	}
141 	tp->tun_pgrp = 0;
142 	selwakeup(&tp->tun_rsel);
143 
144 	TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
145 	return (0);
146 }
147 
148 /*
149  * attach an interface N.B. argument is not same as other drivers
150  */
151 static int
152 tunattach(unit)
153 	int	unit;
154 {
155 	struct ifnet	*ifp = &tunctl[unit].tun_if;
156 	struct sockaddr_in *sin;
157 
158 	ifp->if_unit = unit;
159 	ifp->if_name = "tun";
160 	ifp->if_mtu = TUNMTU;
161 	ifp->if_ioctl = tunioctl;
162 	ifp->if_output = tunoutput;
163 	ifp->if_flags = IFF_POINTOPOINT;
164 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
165 	ifp->if_collisions = 0;
166 	ifp->if_ierrors = 0;
167 	ifp->if_oerrors = 0;
168 	ifp->if_ipackets = 0;
169 	ifp->if_opackets = 0;
170 	if_attach(ifp);
171 	TUNDEBUG("%s%d: tunattach\n", ifp->if_name, ifp->if_unit);
172 	return 0;
173 }
174 
175 static int
176 tuninit(unit)
177 	int	unit;
178 {
179 	struct tunctl	*tp = &tunctl[unit];
180 	struct ifnet	*ifp = &tp->tun_if;
181 
182 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
183 	tp->tun_flags |= TUN_IASET;
184 	TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
185 	return 0;
186 }
187 
188 /*
189  * Process an ioctl request.
190  */
191 int
192 tunioctl(ifp, cmd, data, flag)
193 	struct ifnet *ifp;
194 	int	cmd;
195 	caddr_t	data;
196 	int	flag;
197 {
198 	int		error = 0, s;
199 	struct tunctl	*tp = &tunctl[ifp->if_unit];
200 
201 	s = splimp();
202 	switch(cmd) {
203 	case SIOCSIFADDR:
204 		tuninit(ifp->if_unit);
205 		break;
206 	case SIOCSIFDSTADDR:
207 		tp->tun_flags |= TUN_DSTADDR;
208 		TUNDEBUG("%s%d: destination address set\n", ifp->if_name,
209 		    ifp->if_unit);
210 		break;
211 	default:
212 		error = EINVAL;
213 	}
214 	splx(s);
215 	return (error);
216 }
217 
218 /*
219  * tunoutput - queue packets from higher level ready to put out.
220  */
221 int
222 tunoutput(ifp, m0, dst)
223 	struct ifnet   *ifp;
224 	struct mbuf    *m0;
225 	struct sockaddr *dst;
226 {
227 	struct tunctl	*tp = &tunctl[ifp->if_unit];
228 	struct proc	*p;
229 	int		s;
230 
231 	TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
232 
233 	switch(dst->sa_family) {
234 #ifdef INET
235 	case AF_INET:
236 		s = splimp();
237 		if (IF_QFULL(&ifp->if_snd)) {
238 			IF_DROP(&ifp->if_snd);
239 			m_freem(m0);
240 			splx(s);
241 			ifp->if_collisions++;
242 			return (ENOBUFS);
243 		}
244 		IF_ENQUEUE(&ifp->if_snd, m0);
245 		splx(s);
246 		ifp->if_opackets++;
247 		break;
248 #endif
249 	default:
250 		m_freem(m0);
251 		return EAFNOSUPPORT;
252 	}
253 
254 	if (tp->tun_flags & TUN_RWAIT) {
255 		tp->tun_flags &= ~TUN_RWAIT;
256 		wakeup((caddr_t)tp);
257 	}
258 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
259 		if (tp->tun_pgrp > 0)
260 			gsignal(tp->tun_pgrp, SIGIO);
261 		else if (p = pfind(-tp->tun_pgrp))
262 			psignal(p, SIGIO);
263 	}
264 	selwakeup(&tp->tun_rsel);
265 	return 0;
266 }
267 
268 /*
269  * the cdevsw interface is now pretty minimal.
270  */
271 int
272 tuncioctl(dev, cmd, data, flag)
273 	dev_t		dev;
274 	int		cmd;
275 	caddr_t		data;
276 	int		flag;
277 {
278 	int		unit = minor(dev), s;
279 	struct tunctl	*tp = &tunctl[unit];
280 
281 	switch (cmd) {
282 	case TUNSDEBUG:
283 		tundebug = *(int *)data;
284 		break;
285 	case TUNGDEBUG:
286 		*(int *)data = tundebug;
287 		break;
288 	case FIONBIO:
289 		if (*(int *)data)
290 			tp->tun_flags |= TUN_NBIO;
291 		else
292 			tp->tun_flags &= ~TUN_NBIO;
293 		break;
294 	case FIOASYNC:
295 		if (*(int *)data)
296 			tp->tun_flags |= TUN_ASYNC;
297 		else
298 			tp->tun_flags &= ~TUN_ASYNC;
299 		break;
300 	case FIONREAD:
301 		s = splimp();
302 		if (tp->tun_if.if_snd.ifq_head)
303 			*(int *)data = tp->tun_if.if_snd.ifq_head->m_len;
304 		else
305 			*(int *)data = 0;
306 		splx(s);
307 		break;
308 	case TIOCSPGRP:
309 		tp->tun_pgrp = *(int *)data;
310 		break;
311 	case TIOCGPGRP:
312 		*(int *)data = tp->tun_pgrp;
313 		break;
314 	default:
315 		return (ENOTTY);
316 	}
317 	return (0);
318 }
319 
320 /*
321  * The cdevsw read interface - reads a packet at a time, or at
322  * least as much of a packet as can be read.
323  */
324 int
325 tunread(dev, uio)
326 	dev_t		dev;
327 	struct uio	*uio;
328 {
329 	struct ifnet	*ifp = &tp->tun_if;
330 	struct mbuf	*m, *m0;
331 	struct tunctl	*tp = &tunctl[unit];
332 	int		unit = minor(dev);
333 	int		error=0, len, s;
334 
335 	TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
336 	tp->tun_flags &= ~TUN_RWAIT;
337 
338 	s = splimp();
339 	do {
340 		IF_DEQUEUE(&ifp->if_snd, m0);
341 		if (m0 == 0) {
342 			if (tp->tun_flags & TUN_NBIO) {
343 				splx(s);
344 				return EWOULDBLOCK;
345 			}
346 			tp->tun_flags |= TUN_RWAIT;
347 			tsleep((caddr_t)tp, PZERO + 1, "tunread", 0);
348 		}
349 	} while (m0 == 0);
350 	splx(s);
351 
352 	while (m0 && uio->uio_resid > 0 && error == 0) {
353 		len = MIN(uio->uio_resid, m0->m_len);
354 		if (len == 0)
355 			break;
356 		error = uiomove(mtod(m0, caddr_t), len,
357 		    UIO_READ, uio);
358 		MFREE(m0, m);
359 		m0 = m;
360 	}
361 
362 	if (m0) {
363 		TUNDEBUG("Dropping mbuf\n");
364 		m_freem(m0);
365 	}
366 	return error;
367 }
368 
369 /*
370  * the cdevsw write interface - an atomic write is a packet - or else!
371  */
372 int
373 tunwrite(dev, uio)
374 	int		dev;
375 	struct uio	*uio;
376 {
377 	int		unit = minor (dev);
378 	struct ifnet	*ifp = &(tunctl[unit].tun_if);
379 	struct mbuf	*top, **mp, *m;
380 	int		error=0, s;
381 
382 	TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
383 
384 	if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) {
385 		TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
386 		    uio->uio_resid);
387 		return EIO;
388 	}
389 	top = 0;
390 	mp = &top;
391 	while (error == 0 && uio->uio_resid > 0) {
392 		MGET(m, M_DONTWAIT, MT_DATA);
393 		if (m == 0) {
394 			error = ENOBUFS;
395 			break;
396 		}
397 		m->m_len = MIN(MLEN, uio->uio_resid);
398 		error = uiomove(mtod(m, caddr_t), m->m_len, UIO_WRITE, uio);
399 		*mp = m;
400 		mp = &m->m_next;
401 	}
402 	if (error) {
403 		if (top)
404 			m_freem(top);
405 		return error;
406 	}
407 
408 	/*
409 	 * Place interface pointer before the data
410 	 * for the receiving protocol.
411 	 */
412 	if (top->m_off <= MMAXOFF &&
413 	    top->m_off >= MMINOFF + sizeof(struct ifnet *)) {
414 		top->m_off -= sizeof(struct ifnet *);
415 		top->m_len += sizeof(struct ifnet *);
416 	} else {
417 		MGET(m, M_DONTWAIT, MT_HEADER);
418 		if (m == (struct mbuf *)0)
419 			return (ENOBUFS);
420 		m->m_len = sizeof(struct ifnet *);
421 		m->m_next = top;
422 		top = m;
423 	}
424 	*(mtod(top, struct ifnet **)) = ifp;
425 
426 	s = splimp();
427 	if (IF_QFULL (&ipintrq)) {
428 		IF_DROP(&ipintrq);
429 		splx(s);
430 		ifp->if_collisions++;
431 		m_freem(top);
432 		return ENOBUFS;
433 	}
434 	IF_ENQUEUE(&ipintrq, top);
435 	splx(s);
436 	ifp->if_ipackets++;
437 	schednetisr(NETISR_IP);
438 	return error;
439 }
440 
441 /*
442  * tunselect - the select interface, this is only useful on reads
443  * really. The write detect always returns true, write never blocks
444  * anyway, it either accepts the packet or drops it.
445  */
446 int
447 tunselect(dev, rw, p)
448 	dev_t		dev;
449 	int		rw;
450 	struct proc	*p;
451 {
452 	int		unit = minor(dev), s;
453 	struct tunctl	*tp = &tunctl[unit];
454 	struct ifnet	*ifp = &tp->tun_if;
455 
456 	s = splimp();
457 	TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit);
458 
459 	switch (rw) {
460 	case FREAD:
461 		if (ifp->if_snd.ifq_len > 0) {
462 			splx(s);
463 			TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name,
464 			    ifp->if_unit, ifp->if_snd.ifq_len);
465 			return 1;
466 		}
467 		selrecord(p, &tp->tun_rsel);
468 		break;
469 	case FWRITE:
470 		splx(s);
471 		return 1;
472 	}
473 	splx(s);
474 	TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit);
475 	return 0;
476 }
477 #endif  NTUN
478