Deleted Added
full compact
if_tun.c (205222) if_tun.c (213028)
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 205222 2010-03-16 17:59:12Z qingli $
16 * $FreeBSD: head/sys/net/if_tun.c 213028 2010-09-22 21:02:43Z jhb $
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>

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

160 .f_isfd = 1,
161 .f_attach = NULL,
162 .f_detach = tunkqdetach,
163 .f_event = tunkqwrite,
164};
165
166static struct cdevsw tun_cdevsw = {
167 .d_version = D_VERSION,
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>

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

160 .f_isfd = 1,
161 .f_attach = NULL,
162 .f_detach = tunkqdetach,
163 .f_event = tunkqwrite,
164};
165
166static struct cdevsw tun_cdevsw = {
167 .d_version = D_VERSION,
168 .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
168 .d_flags = D_PSEUDO | 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,
176 .d_name = TUNNAME,

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

339 IFQ_UNLOCK(&ifp->if_snd);
340 }
341
342 mtx_lock(&tp->tun_mtx);
343 if (tp->tun_flags & TUN_RWAIT) {
344 tp->tun_flags &= ~TUN_RWAIT;
345 wakeup(tp);
346 }
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,
176 .d_name = TUNNAME,

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

339 IFQ_UNLOCK(&ifp->if_snd);
340 }
341
342 mtx_lock(&tp->tun_mtx);
343 if (tp->tun_flags & TUN_RWAIT) {
344 tp->tun_flags &= ~TUN_RWAIT;
345 wakeup(tp);
346 }
347 selwakeuppri(&tp->tun_rsel, PZERO + 1);
348 KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
347 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
348 mtx_unlock(&tp->tun_mtx);
349 pgsigio(&tp->tun_sigio, SIGIO, 0);
350 } else
351 mtx_unlock(&tp->tun_mtx);
349 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
350 mtx_unlock(&tp->tun_mtx);
351 pgsigio(&tp->tun_sigio, SIGIO, 0);
352 } else
353 mtx_unlock(&tp->tun_mtx);
352 selwakeuppri(&tp->tun_rsel, PZERO + 1);
353 KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
354}
355
356/* XXX: should return an error code so it can fail. */
357static void
358tuncreate(const char *name, struct cdev *dev)
359{
360 struct tun_softc *sc;
361 struct ifnet *ifp;

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

380 ifp->if_ioctl = tunifioctl;
381 ifp->if_output = tunoutput;
382 ifp->if_start = tunstart;
383 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
384 ifp->if_softc = sc;
385 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
386 ifp->if_snd.ifq_drv_maxlen = 0;
387 IFQ_SET_READY(&ifp->if_snd);
354}
355
356/* XXX: should return an error code so it can fail. */
357static void
358tuncreate(const char *name, struct cdev *dev)
359{
360 struct tun_softc *sc;
361 struct ifnet *ifp;

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

380 ifp->if_ioctl = tunifioctl;
381 ifp->if_output = tunoutput;
382 ifp->if_start = tunstart;
383 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
384 ifp->if_softc = sc;
385 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
386 ifp->if_snd.ifq_drv_maxlen = 0;
387 IFQ_SET_READY(&ifp->if_snd);
388 knlist_init_mtx(&sc->tun_rsel.si_note, NULL);
388 knlist_init_mtx(&sc->tun_rsel.si_note, &sc->tun_mtx);
389 ifp->if_capabilities |= IFCAP_LINKSTATE;
390 ifp->if_capenable |= IFCAP_LINKSTATE;
391
392 if_attach(ifp);
393 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
394 dev->si_drv1 = sc;
395 TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
396 ifp->if_xname, dev2unit(dev));

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

421 mtx_lock(&tp->tun_mtx);
422 if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
423 mtx_unlock(&tp->tun_mtx);
424 return (EBUSY);
425 }
426 tp->tun_pid = td->td_proc->p_pid;
427
428 tp->tun_flags |= TUN_OPEN;
389 ifp->if_capabilities |= IFCAP_LINKSTATE;
390 ifp->if_capenable |= IFCAP_LINKSTATE;
391
392 if_attach(ifp);
393 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
394 dev->si_drv1 = sc;
395 TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
396 ifp->if_xname, dev2unit(dev));

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

421 mtx_lock(&tp->tun_mtx);
422 if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
423 mtx_unlock(&tp->tun_mtx);
424 return (EBUSY);
425 }
426 tp->tun_pid = td->td_proc->p_pid;
427
428 tp->tun_flags |= TUN_OPEN;
429 mtx_unlock(&tp->tun_mtx);
430 ifp = TUN2IFP(tp);
431 if_link_state_change(ifp, LINK_STATE_UP);
432 TUNDEBUG(ifp, "open\n");
429 ifp = TUN2IFP(tp);
430 if_link_state_change(ifp, LINK_STATE_UP);
431 TUNDEBUG(ifp, "open\n");
432 mtx_unlock(&tp->tun_mtx);
433
434 return (0);
435}
436
437/*
438 * tunclose - close the device - mark i/f down & delete
439 * routing info
440 */
441static int
442tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
443{
444 struct tun_softc *tp;
445 struct ifnet *ifp;
433
434 return (0);
435}
436
437/*
438 * tunclose - close the device - mark i/f down & delete
439 * routing info
440 */
441static int
442tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
443{
444 struct tun_softc *tp;
445 struct ifnet *ifp;
446 int s;
447
448 tp = dev->si_drv1;
449 ifp = TUN2IFP(tp);
450
451 mtx_lock(&tp->tun_mtx);
452 tp->tun_flags &= ~TUN_OPEN;
453 tp->tun_pid = 0;
446
447 tp = dev->si_drv1;
448 ifp = TUN2IFP(tp);
449
450 mtx_lock(&tp->tun_mtx);
451 tp->tun_flags &= ~TUN_OPEN;
452 tp->tun_pid = 0;
454 mtx_unlock(&tp->tun_mtx);
455
456 /*
457 * junk all pending output
458 */
459 CURVNET_SET(ifp->if_vnet);
453
454 /*
455 * junk all pending output
456 */
457 CURVNET_SET(ifp->if_vnet);
460 s = splimp();
461 IFQ_PURGE(&ifp->if_snd);
458 IFQ_PURGE(&ifp->if_snd);
462 splx(s);
463
464 if (ifp->if_flags & IFF_UP) {
459
460 if (ifp->if_flags & IFF_UP) {
465 s = splimp();
461 mtx_unlock(&tp->tun_mtx);
466 if_down(ifp);
462 if_down(ifp);
467 splx(s);
463 mtx_lock(&tp->tun_mtx);
468 }
469
470 /* Delete all addresses and routes which reference this interface. */
471 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
472 struct ifaddr *ifa;
473
464 }
465
466 /* Delete all addresses and routes which reference this interface. */
467 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
468 struct ifaddr *ifa;
469
474 s = splimp();
470 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
471 mtx_unlock(&tp->tun_mtx);
475 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
476 /* deal w/IPv4 PtP destination; unlocked read */
477 if (ifa->ifa_addr->sa_family == AF_INET) {
478 rtinit(ifa, (int)RTM_DELETE,
479 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
480 } else {
481 rtinit(ifa, (int)RTM_DELETE, 0);
482 }
483 }
484 if_purgeaddrs(ifp);
472 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
473 /* deal w/IPv4 PtP destination; unlocked read */
474 if (ifa->ifa_addr->sa_family == AF_INET) {
475 rtinit(ifa, (int)RTM_DELETE,
476 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
477 } else {
478 rtinit(ifa, (int)RTM_DELETE, 0);
479 }
480 }
481 if_purgeaddrs(ifp);
485 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
486 splx(s);
482 mtx_lock(&tp->tun_mtx);
487 }
488 if_link_state_change(ifp, LINK_STATE_DOWN);
489 CURVNET_RESTORE();
490
483 }
484 if_link_state_change(ifp, LINK_STATE_DOWN);
485 CURVNET_RESTORE();
486
491 mtx_lock(&tp->tun_mtx);
492 funsetown(&tp->tun_sigio);
493 selwakeuppri(&tp->tun_rsel, PZERO + 1);
487 funsetown(&tp->tun_sigio);
488 selwakeuppri(&tp->tun_rsel, PZERO + 1);
494 KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
489 KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
495 TUNDEBUG (ifp, "closed\n");
496
497 cv_broadcast(&tp->tun_cv);
498 mtx_unlock(&tp->tun_mtx);
499 return (0);
500}
501
502static int
503tuninit(struct ifnet *ifp)
504{
505#ifdef INET
506 struct tun_softc *tp = ifp->if_softc;
507 struct ifaddr *ifa;
508#endif
509 int error = 0;
510
511 TUNDEBUG(ifp, "tuninit\n");
512
490 TUNDEBUG (ifp, "closed\n");
491
492 cv_broadcast(&tp->tun_cv);
493 mtx_unlock(&tp->tun_mtx);
494 return (0);
495}
496
497static int
498tuninit(struct ifnet *ifp)
499{
500#ifdef INET
501 struct tun_softc *tp = ifp->if_softc;
502 struct ifaddr *ifa;
503#endif
504 int error = 0;
505
506 TUNDEBUG(ifp, "tuninit\n");
507
508 mtx_lock(&tp->tun_mtx);
513 ifp->if_flags |= IFF_UP;
514 ifp->if_drv_flags |= IFF_DRV_RUNNING;
515 getmicrotime(&ifp->if_lastchange);
516
517#ifdef INET
518 if_addr_rlock(ifp);
519 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
520 if (ifa->ifa_addr->sa_family == AF_INET) {
521 struct sockaddr_in *si;
522
523 si = (struct sockaddr_in *)ifa->ifa_addr;
509 ifp->if_flags |= IFF_UP;
510 ifp->if_drv_flags |= IFF_DRV_RUNNING;
511 getmicrotime(&ifp->if_lastchange);
512
513#ifdef INET
514 if_addr_rlock(ifp);
515 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
516 if (ifa->ifa_addr->sa_family == AF_INET) {
517 struct sockaddr_in *si;
518
519 si = (struct sockaddr_in *)ifa->ifa_addr;
524 mtx_lock(&tp->tun_mtx);
525 if (si->sin_addr.s_addr)
526 tp->tun_flags |= TUN_IASET;
527
528 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
529 if (si && si->sin_addr.s_addr)
530 tp->tun_flags |= TUN_DSTADDR;
520 if (si->sin_addr.s_addr)
521 tp->tun_flags |= TUN_IASET;
522
523 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
524 if (si && si->sin_addr.s_addr)
525 tp->tun_flags |= TUN_DSTADDR;
531 mtx_unlock(&tp->tun_mtx);
532 }
533 }
534 if_addr_runlock(ifp);
535#endif
526 }
527 }
528 if_addr_runlock(ifp);
529#endif
530 mtx_unlock(&tp->tun_mtx);
536 return (error);
537}
538
539/*
540 * Process an ioctl request.
541 */
542static int
543tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
544{
545 struct ifreq *ifr = (struct ifreq *)data;
546 struct tun_softc *tp = ifp->if_softc;
547 struct ifstat *ifs;
531 return (error);
532}
533
534/*
535 * Process an ioctl request.
536 */
537static int
538tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
539{
540 struct ifreq *ifr = (struct ifreq *)data;
541 struct tun_softc *tp = ifp->if_softc;
542 struct ifstat *ifs;
548 int error = 0, s;
543 int error = 0;
549
544
550 s = splimp();
551 switch(cmd) {
552 case SIOCGIFSTATUS:
553 ifs = (struct ifstat *)data;
554 mtx_lock(&tp->tun_mtx);
555 if (tp->tun_pid)
556 sprintf(ifs->ascii + strlen(ifs->ascii),
557 "\tOpened by PID %d\n", tp->tun_pid);
558 mtx_unlock(&tp->tun_mtx);

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

571 break;
572 case SIOCSIFFLAGS:
573 case SIOCADDMULTI:
574 case SIOCDELMULTI:
575 break;
576 default:
577 error = EINVAL;
578 }
545 switch(cmd) {
546 case SIOCGIFSTATUS:
547 ifs = (struct ifstat *)data;
548 mtx_lock(&tp->tun_mtx);
549 if (tp->tun_pid)
550 sprintf(ifs->ascii + strlen(ifs->ascii),
551 "\tOpened by PID %d\n", tp->tun_pid);
552 mtx_unlock(&tp->tun_mtx);

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

565 break;
566 case SIOCSIFFLAGS:
567 case SIOCADDMULTI:
568 case SIOCDELMULTI:
569 break;
570 default:
571 error = EINVAL;
572 }
579 splx(s);
580 return (error);
581}
582
583/*
584 * tunoutput - queue packets from higher level ready to put out.
585 */
586static int
587tunoutput(

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

677}
678
679/*
680 * the cdevsw interface is now pretty minimal.
681 */
682static int
683tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
684{
573 return (error);
574}
575
576/*
577 * tunoutput - queue packets from higher level ready to put out.
578 */
579static int
580tunoutput(

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

670}
671
672/*
673 * the cdevsw interface is now pretty minimal.
674 */
675static int
676tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
677{
685 int s;
686 int error;
687 struct tun_softc *tp = dev->si_drv1;
688 struct tuninfo *tunp;
689
690 switch (cmd) {
691 case TUNSIFINFO:
692 tunp = (struct tuninfo *)data;
693 if (tunp->mtu < IF_MINMTU)
694 return (EINVAL);
695 if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
696 error = priv_check(td, PRIV_NET_SETIFMTU);
697 if (error)
698 return (error);
699 }
678 int error;
679 struct tun_softc *tp = dev->si_drv1;
680 struct tuninfo *tunp;
681
682 switch (cmd) {
683 case TUNSIFINFO:
684 tunp = (struct tuninfo *)data;
685 if (tunp->mtu < IF_MINMTU)
686 return (EINVAL);
687 if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
688 error = priv_check(td, PRIV_NET_SETIFMTU);
689 if (error)
690 return (error);
691 }
692 mtx_lock(&tp->tun_mtx);
700 TUN2IFP(tp)->if_mtu = tunp->mtu;
701 TUN2IFP(tp)->if_type = tunp->type;
702 TUN2IFP(tp)->if_baudrate = tunp->baudrate;
693 TUN2IFP(tp)->if_mtu = tunp->mtu;
694 TUN2IFP(tp)->if_type = tunp->type;
695 TUN2IFP(tp)->if_baudrate = tunp->baudrate;
696 mtx_unlock(&tp->tun_mtx);
703 break;
704 case TUNGIFINFO:
705 tunp = (struct tuninfo *)data;
697 break;
698 case TUNGIFINFO:
699 tunp = (struct tuninfo *)data;
700 mtx_lock(&tp->tun_mtx);
706 tunp->mtu = TUN2IFP(tp)->if_mtu;
707 tunp->type = TUN2IFP(tp)->if_type;
708 tunp->baudrate = TUN2IFP(tp)->if_baudrate;
701 tunp->mtu = TUN2IFP(tp)->if_mtu;
702 tunp->type = TUN2IFP(tp)->if_type;
703 tunp->baudrate = TUN2IFP(tp)->if_baudrate;
704 mtx_unlock(&tp->tun_mtx);
709 break;
710 case TUNSDEBUG:
711 tundebug = *(int *)data;
712 break;
713 case TUNGDEBUG:
714 *(int *)data = tundebug;
715 break;
716 case TUNSLMODE:

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

727 if (*(int *)data) {
728 tp->tun_flags |= TUN_IFHEAD;
729 tp->tun_flags &= ~TUN_LMODE;
730 } else
731 tp->tun_flags &= ~TUN_IFHEAD;
732 mtx_unlock(&tp->tun_mtx);
733 break;
734 case TUNGIFHEAD:
705 break;
706 case TUNSDEBUG:
707 tundebug = *(int *)data;
708 break;
709 case TUNGDEBUG:
710 *(int *)data = tundebug;
711 break;
712 case TUNSLMODE:

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

723 if (*(int *)data) {
724 tp->tun_flags |= TUN_IFHEAD;
725 tp->tun_flags &= ~TUN_LMODE;
726 } else
727 tp->tun_flags &= ~TUN_IFHEAD;
728 mtx_unlock(&tp->tun_mtx);
729 break;
730 case TUNGIFHEAD:
735 /* Could be unlocked read? */
736 mtx_lock(&tp->tun_mtx);
737 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
738 mtx_unlock(&tp->tun_mtx);
739 break;
740 case TUNSIFMODE:
741 /* deny this if UP */
742 if (TUN2IFP(tp)->if_flags & IFF_UP)
743 return(EBUSY);
744
745 switch (*(int *)data & ~IFF_MULTICAST) {
746 case IFF_POINTOPOINT:
747 case IFF_BROADCAST:
731 mtx_lock(&tp->tun_mtx);
732 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
733 mtx_unlock(&tp->tun_mtx);
734 break;
735 case TUNSIFMODE:
736 /* deny this if UP */
737 if (TUN2IFP(tp)->if_flags & IFF_UP)
738 return(EBUSY);
739
740 switch (*(int *)data & ~IFF_MULTICAST) {
741 case IFF_POINTOPOINT:
742 case IFF_BROADCAST:
743 mtx_lock(&tp->tun_mtx);
748 TUN2IFP(tp)->if_flags &=
749 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
750 TUN2IFP(tp)->if_flags |= *(int *)data;
744 TUN2IFP(tp)->if_flags &=
745 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
746 TUN2IFP(tp)->if_flags |= *(int *)data;
747 mtx_unlock(&tp->tun_mtx);
751 break;
752 default:
753 return(EINVAL);
754 }
755 break;
756 case TUNSIFPID:
757 mtx_lock(&tp->tun_mtx);
758 tp->tun_pid = curthread->td_proc->p_pid;

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

764 mtx_lock(&tp->tun_mtx);
765 if (*(int *)data)
766 tp->tun_flags |= TUN_ASYNC;
767 else
768 tp->tun_flags &= ~TUN_ASYNC;
769 mtx_unlock(&tp->tun_mtx);
770 break;
771 case FIONREAD:
748 break;
749 default:
750 return(EINVAL);
751 }
752 break;
753 case TUNSIFPID:
754 mtx_lock(&tp->tun_mtx);
755 tp->tun_pid = curthread->td_proc->p_pid;

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

761 mtx_lock(&tp->tun_mtx);
762 if (*(int *)data)
763 tp->tun_flags |= TUN_ASYNC;
764 else
765 tp->tun_flags &= ~TUN_ASYNC;
766 mtx_unlock(&tp->tun_mtx);
767 break;
768 case FIONREAD:
772 s = splimp();
773 if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
774 struct mbuf *mb;
775 IFQ_LOCK(&TUN2IFP(tp)->if_snd);
776 IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
769 if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
770 struct mbuf *mb;
771 IFQ_LOCK(&TUN2IFP(tp)->if_snd);
772 IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
777 for( *(int *)data = 0; mb != 0; mb = mb->m_next)
773 for (*(int *)data = 0; mb != NULL; mb = mb->m_next)
778 *(int *)data += mb->m_len;
779 IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
780 } else
781 *(int *)data = 0;
774 *(int *)data += mb->m_len;
775 IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
776 } else
777 *(int *)data = 0;
782 splx(s);
783 break;
784 case FIOSETOWN:
785 return (fsetown(*(int *)data, &tp->tun_sigio));
786
787 case FIOGETOWN:
788 *(int *)data = fgetown(&tp->tun_sigio);
789 return (0);
790

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

808 * least as much of a packet as can be read.
809 */
810static int
811tunread(struct cdev *dev, struct uio *uio, int flag)
812{
813 struct tun_softc *tp = dev->si_drv1;
814 struct ifnet *ifp = TUN2IFP(tp);
815 struct mbuf *m;
778 break;
779 case FIOSETOWN:
780 return (fsetown(*(int *)data, &tp->tun_sigio));
781
782 case FIOGETOWN:
783 *(int *)data = fgetown(&tp->tun_sigio);
784 return (0);
785

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

803 * least as much of a packet as can be read.
804 */
805static int
806tunread(struct cdev *dev, struct uio *uio, int flag)
807{
808 struct tun_softc *tp = dev->si_drv1;
809 struct ifnet *ifp = TUN2IFP(tp);
810 struct mbuf *m;
816 int error=0, len, s;
811 int error=0, len;
817
818 TUNDEBUG (ifp, "read\n");
819 mtx_lock(&tp->tun_mtx);
820 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
821 mtx_unlock(&tp->tun_mtx);
822 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
823 return (EHOSTDOWN);
824 }
825
826 tp->tun_flags &= ~TUN_RWAIT;
812
813 TUNDEBUG (ifp, "read\n");
814 mtx_lock(&tp->tun_mtx);
815 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
816 mtx_unlock(&tp->tun_mtx);
817 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
818 return (EHOSTDOWN);
819 }
820
821 tp->tun_flags &= ~TUN_RWAIT;
827 mtx_unlock(&tp->tun_mtx);
828
822
829 s = splimp();
830 do {
831 IFQ_DEQUEUE(&ifp->if_snd, m);
832 if (m == NULL) {
833 if (flag & O_NONBLOCK) {
823 do {
824 IFQ_DEQUEUE(&ifp->if_snd, m);
825 if (m == NULL) {
826 if (flag & O_NONBLOCK) {
834 splx(s);
827 mtx_unlock(&tp->tun_mtx);
835 return (EWOULDBLOCK);
836 }
828 return (EWOULDBLOCK);
829 }
837 mtx_lock(&tp->tun_mtx);
838 tp->tun_flags |= TUN_RWAIT;
830 tp->tun_flags |= TUN_RWAIT;
839 mtx_unlock(&tp->tun_mtx);
840 if ((error = tsleep(tp, PCATCH | (PZERO + 1),
841 "tunread", 0)) != 0) {
842 splx(s);
831 error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1),
832 "tunread", 0);
833 if (error != 0) {
834 mtx_unlock(&tp->tun_mtx);
843 return (error);
844 }
845 }
846 } while (m == NULL);
835 return (error);
836 }
837 }
838 } while (m == NULL);
847 splx(s);
839 mtx_unlock(&tp->tun_mtx);
848
849 while (m && uio->uio_resid > 0 && error == 0) {
850 len = min(uio->uio_resid, m->m_len);
851 if (len != 0)
852 error = uiomove(mtod(m, void *), len, uio);
853 m = m_free(m);
854 }
855

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

952/*
953 * tunpoll - the poll interface, this is only useful on reads
954 * really. The write detect always returns true, write never blocks
955 * anyway, it either accepts the packet or drops it.
956 */
957static int
958tunpoll(struct cdev *dev, int events, struct thread *td)
959{
840
841 while (m && uio->uio_resid > 0 && error == 0) {
842 len = min(uio->uio_resid, m->m_len);
843 if (len != 0)
844 error = uiomove(mtod(m, void *), len, uio);
845 m = m_free(m);
846 }
847

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

944/*
945 * tunpoll - the poll interface, this is only useful on reads
946 * really. The write detect always returns true, write never blocks
947 * anyway, it either accepts the packet or drops it.
948 */
949static int
950tunpoll(struct cdev *dev, int events, struct thread *td)
951{
960 int s;
961 struct tun_softc *tp = dev->si_drv1;
962 struct ifnet *ifp = TUN2IFP(tp);
963 int revents = 0;
964 struct mbuf *m;
965
952 struct tun_softc *tp = dev->si_drv1;
953 struct ifnet *ifp = TUN2IFP(tp);
954 int revents = 0;
955 struct mbuf *m;
956
966 s = splimp();
967 TUNDEBUG(ifp, "tunpoll\n");
968
969 if (events & (POLLIN | POLLRDNORM)) {
970 IFQ_LOCK(&ifp->if_snd);
971 IFQ_POLL_NOLOCK(&ifp->if_snd, m);
972 if (m != NULL) {
973 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
974 revents |= events & (POLLIN | POLLRDNORM);
975 } else {
976 TUNDEBUG(ifp, "tunpoll waiting\n");
977 selrecord(td, &tp->tun_rsel);
978 }
979 IFQ_UNLOCK(&ifp->if_snd);
980 }
981 if (events & (POLLOUT | POLLWRNORM))
982 revents |= events & (POLLOUT | POLLWRNORM);
983
957 TUNDEBUG(ifp, "tunpoll\n");
958
959 if (events & (POLLIN | POLLRDNORM)) {
960 IFQ_LOCK(&ifp->if_snd);
961 IFQ_POLL_NOLOCK(&ifp->if_snd, m);
962 if (m != NULL) {
963 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
964 revents |= events & (POLLIN | POLLRDNORM);
965 } else {
966 TUNDEBUG(ifp, "tunpoll waiting\n");
967 selrecord(td, &tp->tun_rsel);
968 }
969 IFQ_UNLOCK(&ifp->if_snd);
970 }
971 if (events & (POLLOUT | POLLWRNORM))
972 revents |= events & (POLLOUT | POLLWRNORM);
973
984 splx(s);
985 return (revents);
986}
987
988/*
989 * tunkqfilter - support for the kevent() system call.
990 */
991static int
992tunkqfilter(struct cdev *dev, struct knote *kn)
993{
974 return (revents);
975}
976
977/*
978 * tunkqfilter - support for the kevent() system call.
979 */
980static int
981tunkqfilter(struct cdev *dev, struct knote *kn)
982{
994 int s;
995 struct tun_softc *tp = dev->si_drv1;
996 struct ifnet *ifp = TUN2IFP(tp);
997
983 struct tun_softc *tp = dev->si_drv1;
984 struct ifnet *ifp = TUN2IFP(tp);
985
998 s = splimp();
999 switch(kn->kn_filter) {
1000 case EVFILT_READ:
1001 TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
1002 ifp->if_xname, dev2unit(dev));
1003 kn->kn_fop = &tun_read_filterops;
1004 break;
1005
1006 case EVFILT_WRITE:
1007 TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
1008 ifp->if_xname, dev2unit(dev));
1009 kn->kn_fop = &tun_write_filterops;
1010 break;
1011
1012 default:
1013 TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
1014 ifp->if_xname, dev2unit(dev));
986 switch(kn->kn_filter) {
987 case EVFILT_READ:
988 TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
989 ifp->if_xname, dev2unit(dev));
990 kn->kn_fop = &tun_read_filterops;
991 break;
992
993 case EVFILT_WRITE:
994 TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
995 ifp->if_xname, dev2unit(dev));
996 kn->kn_fop = &tun_write_filterops;
997 break;
998
999 default:
1000 TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
1001 ifp->if_xname, dev2unit(dev));
1015 splx(s);
1016 return(EINVAL);
1017 }
1002 return(EINVAL);
1003 }
1018 splx(s);
1019
1004
1020 kn->kn_hook = (caddr_t) dev;
1005 kn->kn_hook = tp;
1021 knlist_add(&tp->tun_rsel.si_note, kn, 0);
1022
1023 return (0);
1024}
1025
1026/*
1027 * Return true of there is data in the interface queue.
1028 */
1029static int
1030tunkqread(struct knote *kn, long hint)
1031{
1006 knlist_add(&tp->tun_rsel.si_note, kn, 0);
1007
1008 return (0);
1009}
1010
1011/*
1012 * Return true of there is data in the interface queue.
1013 */
1014static int
1015tunkqread(struct knote *kn, long hint)
1016{
1032 int ret, s;
1033 struct cdev *dev = (struct cdev *)(kn->kn_hook);
1034 struct tun_softc *tp = dev->si_drv1;
1017 int ret;
1018 struct tun_softc *tp = kn->kn_hook;
1019 struct cdev *dev = tp->tun_dev;
1035 struct ifnet *ifp = TUN2IFP(tp);
1036
1020 struct ifnet *ifp = TUN2IFP(tp);
1021
1037 s = splimp();
1038 if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
1039 TUNDEBUG(ifp,
1040 "%s have data in the queue. Len = %d, minor = %#x\n",
1041 ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
1042 ret = 1;
1043 } else {
1044 TUNDEBUG(ifp,
1045 "%s waiting for data, minor = %#x\n", ifp->if_xname,
1046 dev2unit(dev));
1047 ret = 0;
1048 }
1022 if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
1023 TUNDEBUG(ifp,
1024 "%s have data in the queue. Len = %d, minor = %#x\n",
1025 ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
1026 ret = 1;
1027 } else {
1028 TUNDEBUG(ifp,
1029 "%s waiting for data, minor = %#x\n", ifp->if_xname,
1030 dev2unit(dev));
1031 ret = 0;
1032 }
1049 splx(s);
1050
1051 return (ret);
1052}
1053
1054/*
1055 * Always can write, always return MTU in kn->data.
1056 */
1057static int
1058tunkqwrite(struct knote *kn, long hint)
1059{
1033
1034 return (ret);
1035}
1036
1037/*
1038 * Always can write, always return MTU in kn->data.
1039 */
1040static int
1041tunkqwrite(struct knote *kn, long hint)
1042{
1060 int s;
1061 struct tun_softc *tp = ((struct cdev *)kn->kn_hook)->si_drv1;
1043 struct tun_softc *tp = kn->kn_hook;
1062 struct ifnet *ifp = TUN2IFP(tp);
1063
1044 struct ifnet *ifp = TUN2IFP(tp);
1045
1064 s = splimp();
1065 kn->kn_data = ifp->if_mtu;
1046 kn->kn_data = ifp->if_mtu;
1066 splx(s);
1067
1068 return (1);
1069}
1070
1071static void
1072tunkqdetach(struct knote *kn)
1073{
1047
1048 return (1);
1049}
1050
1051static void
1052tunkqdetach(struct knote *kn)
1053{
1074 struct tun_softc *tp = ((struct cdev *)kn->kn_hook)->si_drv1;
1054 struct tun_softc *tp = kn->kn_hook;
1075
1076 knlist_remove(&tp->tun_rsel.si_note, kn, 0);
1077}
1055
1056 knlist_remove(&tp->tun_rsel.si_note, kn, 0);
1057}