Deleted Added
sdiff udiff text old ( 83805 ) new ( 90227 )
full compact
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 90227 2002-02-05 02:00:56Z dillon $
17 */
18
19#include "opt_inet.h"
20
21#include <sys/param.h>
22#include <sys/proc.h>
23#include <sys/systm.h>
24#include <sys/mbuf.h>

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

631 * The cdevsw read interface - reads a packet at a time, or at
632 * least as much of a packet as can be read.
633 */
634static int
635tunread(dev_t dev, struct uio *uio, int flag)
636{
637 struct tun_softc *tp = dev->si_drv1;
638 struct ifnet *ifp = &tp->tun_if;
639 struct mbuf *m;
640 int error=0, len, s;
641
642 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
643 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
644 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
645 ifp->if_unit, tp->tun_flags);
646 return EHOSTDOWN;
647 }
648
649 tp->tun_flags &= ~TUN_RWAIT;
650
651 s = splimp();
652 do {
653 IF_DEQUEUE(&ifp->if_snd, m);
654 if (m == NULL) {
655 if (flag & IO_NDELAY) {
656 splx(s);
657 return EWOULDBLOCK;
658 }
659 tp->tun_flags |= TUN_RWAIT;
660 if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
661 "tunread", 0)) != 0) {
662 splx(s);
663 return error;
664 }
665 }
666 } while (m == NULL);
667 splx(s);
668
669 while (m && uio->uio_resid > 0 && error == 0) {
670 len = min(uio->uio_resid, m->m_len);
671 if (len != 0)
672 error = uiomove(mtod(m, caddr_t), len, uio);
673 m = m_free(m);
674 }
675
676 if (m) {
677 TUNDEBUG("%s%d: Dropping mbuf\n", ifp->if_name, ifp->if_unit);
678 m_freem(m);
679 }
680 return error;
681}
682
683/*
684 * the cdevsw write interface - an atomic write is a packet - or else!
685 */
686static int

--- 133 unchanged lines hidden ---