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 111741 2003-03-02 15:50:23Z des $
35 * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
36 */
37
38#include "opt_inet.h"
39
40#include <sys/param.h>
41#include <sys/conf.h>
42#include <sys/filedesc.h>
--- 33 unchanged lines hidden (view full) ---
76
77#define TAP "tap"
78#define VMNET "vmnet"
79#define TAPMAXUNIT 0x7fff
80#define VMNET_DEV_MASK 0x00800000
81 /* 0x007f00ff */
82
83/* module */
84static int tapmodevent(module_t, int, void *);
85
86/* device */
87static void tapclone(void *, char *, int, dev_t *);
88static void tapcreate(dev_t);
89
90/* network interface */
91static void tapifstart(struct ifnet *);
92static int tapifioctl(struct ifnet *, u_long, caddr_t);
--- 108 unchanged lines hidden (view full) ---
201
202 while ((tp = SLIST_FIRST(&taphead)) != NULL) {
203 SLIST_REMOVE_HEAD(&taphead, tap_next);
204
205 ifp = &tp->tap_if;
206
207 TAPDEBUG("detaching %s%d\n", ifp->if_name,ifp->if_unit);
208
209 KASSERT(!(tp->tap_flags & TAP_OPEN),
210 ("%s%d flags is out of sync", ifp->if_name,
211 ifp->if_unit));
212
213 /* XXX makedev check? nah.. not right now :) */
214
215 s = splimp();
216 ether_ifdetach(ifp);
217 splx(s);
218
219 free(tp, M_TAP);
220 }
221
222 if (tapbasedev != NOUDEV)
223 destroy_dev(udev2dev(tapbasedev, 0));
224
225
226 break;
227
228 default:
229 return (EOPNOTSUPP);
230 }
--- 18 unchanged lines hidden (view full) ---
249 char *device_name = name;
250 struct resource *r = NULL;
251
252 if (*dev != NODEV)
253 return;
254
255 if (strcmp(device_name, TAP) == 0) {
256 /* get first free tap unit */
257 r = rman_reserve_resource(tapunits, 0, TAPMAXUNIT, 1,
258 RF_ALLOCATED | RF_ACTIVE, NULL);
259 unit = rman_get_start(r);
260 minor = unit2minor(unit);
261 }
262 else if (strcmp(device_name, VMNET) == 0) {
263 /* get first free vmnet unit */
264 r = rman_reserve_resource(vmnetunits, 0, TAPMAXUNIT, 1,
265 RF_ALLOCATED | RF_ACTIVE, NULL);
266 unit = rman_get_start(r);
267 minor = unit2minor(unit) | VMNET_DEV_MASK;
268 }
269
270 if (r != NULL) { /* need cloning */
271 TAPDEBUG("%s%d is available. minor = %#x\n",
272 device_name, unit, minor);
273
274 error = rman_release_resource(r);
275 KASSERT((error == 0), ("Could not release tap/vmnet unit"));
276
277 /* check if device for the unit has been created */
278 *dev = makedev(CDEV_MAJOR, minor);
279 if ((*dev)->si_flags & SI_NAMED) {
280 TAPDEBUG("%s%d device exists. minor = %#x\n",
281 device_name, unit, minor);
282 return; /* device has been created */
283 }
284 } else { /* try to match name/unit, first try tap then vmnet */
285 device_name = TAP;
286 if (dev_stdclone(name, NULL, device_name, &unit) != 1) {
287 device_name = VMNET;
288
--- 45 unchanged lines hidden (view full) ---
334 name = VMNET;
335 tp->tap_flags |= TAP_VMNET;
336 } else
337 name = TAP;
338
339 TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev));
340
341 if (!(dev->si_flags & SI_NAMED))
342 dev = make_dev(&tap_cdevsw, minor(dev), UID_ROOT, GID_WHEEL,
343 0600, "%s%d", name, unit);
344
345 /* generate fake MAC address: 00 bd xx xx xx unit_no */
346 macaddr_hi = htons(0x00bd);
347 bcopy(&macaddr_hi, &tp->arpcom.ac_enaddr[0], sizeof(short));
348 bcopy(&ticks, &tp->arpcom.ac_enaddr[2], sizeof(long));
349 tp->arpcom.ac_enaddr[5] = (u_char)unit;
350
351 /* fill the rest and attach interface */
352 ifp = &tp->tap_if;
353 ifp->if_softc = tp;
354 ifp->if_unit = unit;
355 ifp->if_name = name;
356 ifp->if_init = tapifinit;
357 ifp->if_start = tapifstart;
358 ifp->if_ioctl = tapifioctl;
359 ifp->if_mtu = ETHERMTU;
360 ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
361 ifp->if_snd.ifq_maxlen = ifqmaxlen;
362
363 dev->si_drv1 = tp;
364
365 s = splimp();
366 ether_ifattach(ifp, tp->arpcom.ac_enaddr);
367 splx(s);
368
369 tp->tap_flags |= TAP_INITED;
370
371 TAPDEBUG("interface %s%d is created. minor = %#x\n",
372 ifp->if_name, ifp->if_unit, minor(dev));
373} /* tapcreate */
374
375
376/*
377 * tapopen
378 *
379 * to open tunnel. must be superuser
380 */
381static int
382tapopen(dev, flag, mode, td)
383 dev_t dev;
384 int flag;
385 int mode;
--- 4 unchanged lines hidden (view full) ---
390 struct resource *r = NULL;
391
392 if ((error = suser(td)) != 0)
393 return (error);
394
395 unit = dev2unit(dev) & TAPMAXUNIT;
396
397 if (minor(dev) & VMNET_DEV_MASK)
398 r = rman_reserve_resource(vmnetunits, unit, unit, 1,
399 RF_ALLOCATED | RF_ACTIVE, NULL);
400 else
401 r = rman_reserve_resource(tapunits, unit, unit, 1,
402 RF_ALLOCATED | RF_ACTIVE, NULL);
403
404 if (r == NULL)
405 return (EBUSY);
406
407 dev->si_flags &= ~SI_CHEAPCLONE;
408
409 tp = dev->si_drv1;
410 if (tp == NULL) {
411 tapcreate(dev);
412 tp = dev->si_drv1;
413 }
414
415 KASSERT(!(tp->tap_flags & TAP_OPEN),
416 ("%s%d flags is out of sync", tp->tap_if.if_name, unit));
417
418 bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr));
419
420 tp->tap_unit = r;
421 tp->tap_pid = td->td_proc->p_pid;
422 tp->tap_flags |= TAP_OPEN;
423
424 TAPDEBUG("%s%d is open. minor = %#x\n",
425 tp->tap_if.if_name, unit, minor(dev));
426
427 return (0);
428} /* tapopen */
429
430
431/*
432 * tapclose
--- 29 unchanged lines hidden (view full) ---
462 /* find internet addresses and delete routes */
463 struct ifaddr *ifa = NULL;
464
465 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
466 if (ifa->ifa_addr->sa_family == AF_INET) {
467 rtinit(ifa, (int)RTM_DELETE, 0);
468
469 /* remove address from interface */
470 bzero(ifa->ifa_addr,
471 sizeof(*(ifa->ifa_addr)));
472 bzero(ifa->ifa_dstaddr,
473 sizeof(*(ifa->ifa_dstaddr)));
474 bzero(ifa->ifa_netmask,
475 sizeof(*(ifa->ifa_netmask)));
476 }
477 }
478
479 ifp->if_flags &= ~IFF_RUNNING;
480 }
481 splx(s);
482 }
483
484 funsetown(&tp->tap_sigio);
485 selwakeup(&tp->tap_rsel);
486
487 tp->tap_flags &= ~TAP_OPEN;
488 tp->tap_pid = 0;
489 error = rman_release_resource(tp->tap_unit);
490 KASSERT((error == 0),
491 ("%s%d could not release unit", ifp->if_name, ifp->if_unit));
492 tp->tap_unit = NULL;
493
494 TAPDEBUG("%s%d is closed. minor = %#x\n",
495 ifp->if_name, ifp->if_unit, minor(dev));
496
497 return (0);
498} /* tapclose */
499
500
501/*
502 * tapifinit
--- 23 unchanged lines hidden (view full) ---
526 * Process an ioctl request on network interface
527 */
528static int
529tapifioctl(ifp, cmd, data)
530 struct ifnet *ifp;
531 u_long cmd;
532 caddr_t data;
533{
534 struct tap_softc *tp = (struct tap_softc *)(ifp->if_softc);
535 struct ifstat *ifs = NULL;
536 int s, dummy;
537
538 switch (cmd) {
539 case SIOCSIFFLAGS: /* XXX -- just like vmnet does */
540 case SIOCADDMULTI:
541 case SIOCDELMULTI:
542 break;
--- 16 unchanged lines hidden (view full) ---
559 return (dummy);
560 }
561
562 return (0);
563} /* tapifioctl */
564
565
566/*
567 * tapifstart
568 *
569 * queue packets from higher level ready to put out
570 */
571static void
572tapifstart(ifp)
573 struct ifnet *ifp;
574{
575 struct tap_softc *tp = ifp->if_softc;
576 int s;
577
578 TAPDEBUG("%s%d starting\n", ifp->if_name, ifp->if_unit);
579
580 /*
581 * do not junk pending output if we are in VMnet mode.
582 * XXX: can this do any harm because of queue overflow?
583 */
584
585 if (((tp->tap_flags & TAP_VMNET) == 0) &&
586 ((tp->tap_flags & TAP_READY) != TAP_READY)) {
587 struct mbuf *m = NULL;
588
589 TAPDEBUG("%s%d not ready, tap_flags = 0x%x\n", ifp->if_name,
590 ifp->if_unit, tp->tap_flags);
591
592 s = splimp();
593 do {
594 IF_DEQUEUE(&ifp->if_snd, m);
595 if (m != NULL)
596 m_freem(m);
597 ifp->if_oerrors ++;
--- 34 unchanged lines hidden (view full) ---
632 dev_t dev;
633 u_long cmd;
634 caddr_t data;
635 int flag;
636 struct thread *td;
637{
638 struct tap_softc *tp = dev->si_drv1;
639 struct ifnet *ifp = &tp->tap_if;
640 struct tapinfo *tapp = NULL;
641 int s;
642 int f;
643
644 switch (cmd) {
645 case TAPSIFINFO:
646 s = splimp();
647 tapp = (struct tapinfo *)data;
648 ifp->if_mtu = tapp->mtu;
649 ifp->if_type = tapp->type;
650 ifp->if_baudrate = tapp->baudrate;
651 splx(s);
652 break;
653
654 case TAPGIFINFO:
655 tapp = (struct tapinfo *)data;
656 tapp->mtu = ifp->if_mtu;
657 tapp->type = ifp->if_type;
658 tapp->baudrate = ifp->if_baudrate;
659 break;
660
661 case TAPSDEBUG:
662 tapdebug = *(int *)data;
663 break;
664
665 case TAPGDEBUG:
666 *(int *)data = tapdebug;
667 break;
--- 83 unchanged lines hidden (view full) ---
751 struct uio *uio;
752 int flag;
753{
754 struct tap_softc *tp = dev->si_drv1;
755 struct ifnet *ifp = &tp->tap_if;
756 struct mbuf *m = NULL;
757 int error = 0, len, s;
758
759 TAPDEBUG("%s%d reading, minor = %#x\n",
760 ifp->if_name, ifp->if_unit, minor(dev));
761
762 if ((tp->tap_flags & TAP_READY) != TAP_READY) {
763 TAPDEBUG("%s%d not ready. minor = %#x, tap_flags = 0x%x\n",
764 ifp->if_name, ifp->if_unit, minor(dev), tp->tap_flags);
765
766 return (EHOSTDOWN);
767 }
--- 4 unchanged lines hidden (view full) ---
772 do {
773 s = splimp();
774 IF_DEQUEUE(&ifp->if_snd, m);
775 splx(s);
776
777 if (m == NULL) {
778 if (flag & IO_NDELAY)
779 return (EWOULDBLOCK);
780
781 tp->tap_flags |= TAP_RWAIT;
782 error = tsleep((caddr_t)tp,PCATCH|(PZERO+1),"taprd",0);
783 if (error)
784 return (error);
785 }
786 } while (m == NULL);
787
788 /* feed packet to bpf */
--- 5 unchanged lines hidden (view full) ---
794 if (len == 0)
795 break;
796
797 error = uiomove(mtod(m, void *), len, uio);
798 m = m_free(m);
799 }
800
801 if (m != NULL) {
802 TAPDEBUG("%s%d dropping mbuf, minor = %#x\n", ifp->if_name,
803 ifp->if_unit, minor(dev));
804 m_freem(m);
805 }
806
807 return (error);
808} /* tapread */
809
810
--- 6 unchanged lines hidden (view full) ---
817tapwrite(dev, uio, flag)
818 dev_t dev;
819 struct uio *uio;
820 int flag;
821{
822 struct tap_softc *tp = dev->si_drv1;
823 struct ifnet *ifp = &tp->tap_if;
824 struct mbuf *top = NULL, **mp = NULL, *m = NULL;
825 int error = 0, tlen, mlen;
826
827 TAPDEBUG("%s%d writting, minor = %#x\n",
828 ifp->if_name, ifp->if_unit, minor(dev));
829
830 if (uio->uio_resid == 0)
831 return (0);
832
833 if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) {
834 TAPDEBUG("%s%d invalid packet len = %d, minor = %#x\n",
835 ifp->if_name, ifp->if_unit, uio->uio_resid, minor(dev));
--- 28 unchanged lines hidden (view full) ---
864 ifp->if_ierrors ++;
865 if (top)
866 m_freem(top);
867 return (error);
868 }
869
870 top->m_pkthdr.len = tlen;
871 top->m_pkthdr.rcvif = ifp;
872
873 /* Pass packet up to parent. */
874 (*ifp->if_input)(ifp, top);
875 ifp->if_ipackets ++; /* ibytes are counted in parent */
876
877 return (0);
878} /* tapwrite */
879
880
--- 7 unchanged lines hidden (view full) ---
888static int
889tappoll(dev, events, td)
890 dev_t dev;
891 int events;
892 struct thread *td;
893{
894 struct tap_softc *tp = dev->si_drv1;
895 struct ifnet *ifp = &tp->tap_if;
896 int s, revents = 0;
897
898 TAPDEBUG("%s%d polling, minor = %#x\n",
899 ifp->if_name, ifp->if_unit, minor(dev));
900
901 s = splimp();
902 if (events & (POLLIN | POLLRDNORM)) {
903 if (ifp->if_snd.ifq_len > 0) {
904 TAPDEBUG("%s%d have data in queue. len = %d, " \
905 "minor = %#x\n", ifp->if_name, ifp->if_unit,
906 ifp->if_snd.ifq_len, minor(dev));
--- 16 unchanged lines hidden ---
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 111741 2003-03-02 15:50:23Z des $
35 * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
36 */
37
38#include "opt_inet.h"
39
40#include <sys/param.h>
41#include <sys/conf.h>
42#include <sys/filedesc.h>
--- 33 unchanged lines hidden (view full) ---
76
77#define TAP "tap"
78#define VMNET "vmnet"
79#define TAPMAXUNIT 0x7fff
80#define VMNET_DEV_MASK 0x00800000
81 /* 0x007f00ff */
82
83/* module */
84static int tapmodevent(module_t, int, void *);
85
86/* device */
87static void tapclone(void *, char *, int, dev_t *);
88static void tapcreate(dev_t);
89
90/* network interface */
91static void tapifstart(struct ifnet *);
92static int tapifioctl(struct ifnet *, u_long, caddr_t);
--- 108 unchanged lines hidden (view full) ---
201
202 while ((tp = SLIST_FIRST(&taphead)) != NULL) {
203 SLIST_REMOVE_HEAD(&taphead, tap_next);
204
205 ifp = &tp->tap_if;
206
207 TAPDEBUG("detaching %s%d\n", ifp->if_name,ifp->if_unit);
208
209 KASSERT(!(tp->tap_flags & TAP_OPEN),
210 ("%s%d flags is out of sync", ifp->if_name,
211 ifp->if_unit));
212
213 /* XXX makedev check? nah.. not right now :) */
214
215 s = splimp();
216 ether_ifdetach(ifp);
217 splx(s);
218
219 free(tp, M_TAP);
220 }
221
222 if (tapbasedev != NOUDEV)
223 destroy_dev(udev2dev(tapbasedev, 0));
224
225
226 break;
227
228 default:
229 return (EOPNOTSUPP);
230 }
--- 18 unchanged lines hidden (view full) ---
249 char *device_name = name;
250 struct resource *r = NULL;
251
252 if (*dev != NODEV)
253 return;
254
255 if (strcmp(device_name, TAP) == 0) {
256 /* get first free tap unit */
257 r = rman_reserve_resource(tapunits, 0, TAPMAXUNIT, 1,
258 RF_ALLOCATED | RF_ACTIVE, NULL);
259 unit = rman_get_start(r);
260 minor = unit2minor(unit);
261 }
262 else if (strcmp(device_name, VMNET) == 0) {
263 /* get first free vmnet unit */
264 r = rman_reserve_resource(vmnetunits, 0, TAPMAXUNIT, 1,
265 RF_ALLOCATED | RF_ACTIVE, NULL);
266 unit = rman_get_start(r);
267 minor = unit2minor(unit) | VMNET_DEV_MASK;
268 }
269
270 if (r != NULL) { /* need cloning */
271 TAPDEBUG("%s%d is available. minor = %#x\n",
272 device_name, unit, minor);
273
274 error = rman_release_resource(r);
275 KASSERT((error == 0), ("Could not release tap/vmnet unit"));
276
277 /* check if device for the unit has been created */
278 *dev = makedev(CDEV_MAJOR, minor);
279 if ((*dev)->si_flags & SI_NAMED) {
280 TAPDEBUG("%s%d device exists. minor = %#x\n",
281 device_name, unit, minor);
282 return; /* device has been created */
283 }
284 } else { /* try to match name/unit, first try tap then vmnet */
285 device_name = TAP;
286 if (dev_stdclone(name, NULL, device_name, &unit) != 1) {
287 device_name = VMNET;
288
--- 45 unchanged lines hidden (view full) ---
334 name = VMNET;
335 tp->tap_flags |= TAP_VMNET;
336 } else
337 name = TAP;
338
339 TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev));
340
341 if (!(dev->si_flags & SI_NAMED))
342 dev = make_dev(&tap_cdevsw, minor(dev), UID_ROOT, GID_WHEEL,
343 0600, "%s%d", name, unit);
344
345 /* generate fake MAC address: 00 bd xx xx xx unit_no */
346 macaddr_hi = htons(0x00bd);
347 bcopy(&macaddr_hi, &tp->arpcom.ac_enaddr[0], sizeof(short));
348 bcopy(&ticks, &tp->arpcom.ac_enaddr[2], sizeof(long));
349 tp->arpcom.ac_enaddr[5] = (u_char)unit;
350
351 /* fill the rest and attach interface */
352 ifp = &tp->tap_if;
353 ifp->if_softc = tp;
354 ifp->if_unit = unit;
355 ifp->if_name = name;
356 ifp->if_init = tapifinit;
357 ifp->if_start = tapifstart;
358 ifp->if_ioctl = tapifioctl;
359 ifp->if_mtu = ETHERMTU;
360 ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
361 ifp->if_snd.ifq_maxlen = ifqmaxlen;
362
363 dev->si_drv1 = tp;
364
365 s = splimp();
366 ether_ifattach(ifp, tp->arpcom.ac_enaddr);
367 splx(s);
368
369 tp->tap_flags |= TAP_INITED;
370
371 TAPDEBUG("interface %s%d is created. minor = %#x\n",
372 ifp->if_name, ifp->if_unit, minor(dev));
373} /* tapcreate */
374
375
376/*
377 * tapopen
378 *
379 * to open tunnel. must be superuser
380 */
381static int
382tapopen(dev, flag, mode, td)
383 dev_t dev;
384 int flag;
385 int mode;
--- 4 unchanged lines hidden (view full) ---
390 struct resource *r = NULL;
391
392 if ((error = suser(td)) != 0)
393 return (error);
394
395 unit = dev2unit(dev) & TAPMAXUNIT;
396
397 if (minor(dev) & VMNET_DEV_MASK)
398 r = rman_reserve_resource(vmnetunits, unit, unit, 1,
399 RF_ALLOCATED | RF_ACTIVE, NULL);
400 else
401 r = rman_reserve_resource(tapunits, unit, unit, 1,
402 RF_ALLOCATED | RF_ACTIVE, NULL);
403
404 if (r == NULL)
405 return (EBUSY);
406
407 dev->si_flags &= ~SI_CHEAPCLONE;
408
409 tp = dev->si_drv1;
410 if (tp == NULL) {
411 tapcreate(dev);
412 tp = dev->si_drv1;
413 }
414
415 KASSERT(!(tp->tap_flags & TAP_OPEN),
416 ("%s%d flags is out of sync", tp->tap_if.if_name, unit));
417
418 bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr));
419
420 tp->tap_unit = r;
421 tp->tap_pid = td->td_proc->p_pid;
422 tp->tap_flags |= TAP_OPEN;
423
424 TAPDEBUG("%s%d is open. minor = %#x\n",
425 tp->tap_if.if_name, unit, minor(dev));
426
427 return (0);
428} /* tapopen */
429
430
431/*
432 * tapclose
--- 29 unchanged lines hidden (view full) ---
462 /* find internet addresses and delete routes */
463 struct ifaddr *ifa = NULL;
464
465 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
466 if (ifa->ifa_addr->sa_family == AF_INET) {
467 rtinit(ifa, (int)RTM_DELETE, 0);
468
469 /* remove address from interface */
470 bzero(ifa->ifa_addr,
471 sizeof(*(ifa->ifa_addr)));
472 bzero(ifa->ifa_dstaddr,
473 sizeof(*(ifa->ifa_dstaddr)));
474 bzero(ifa->ifa_netmask,
475 sizeof(*(ifa->ifa_netmask)));
476 }
477 }
478
479 ifp->if_flags &= ~IFF_RUNNING;
480 }
481 splx(s);
482 }
483
484 funsetown(&tp->tap_sigio);
485 selwakeup(&tp->tap_rsel);
486
487 tp->tap_flags &= ~TAP_OPEN;
488 tp->tap_pid = 0;
489 error = rman_release_resource(tp->tap_unit);
490 KASSERT((error == 0),
491 ("%s%d could not release unit", ifp->if_name, ifp->if_unit));
492 tp->tap_unit = NULL;
493
494 TAPDEBUG("%s%d is closed. minor = %#x\n",
495 ifp->if_name, ifp->if_unit, minor(dev));
496
497 return (0);
498} /* tapclose */
499
500
501/*
502 * tapifinit
--- 23 unchanged lines hidden (view full) ---
526 * Process an ioctl request on network interface
527 */
528static int
529tapifioctl(ifp, cmd, data)
530 struct ifnet *ifp;
531 u_long cmd;
532 caddr_t data;
533{
534 struct tap_softc *tp = (struct tap_softc *)(ifp->if_softc);
535 struct ifstat *ifs = NULL;
536 int s, dummy;
537
538 switch (cmd) {
539 case SIOCSIFFLAGS: /* XXX -- just like vmnet does */
540 case SIOCADDMULTI:
541 case SIOCDELMULTI:
542 break;
--- 16 unchanged lines hidden (view full) ---
559 return (dummy);
560 }
561
562 return (0);
563} /* tapifioctl */
564
565
566/*
567 * tapifstart
568 *
569 * queue packets from higher level ready to put out
570 */
571static void
572tapifstart(ifp)
573 struct ifnet *ifp;
574{
575 struct tap_softc *tp = ifp->if_softc;
576 int s;
577
578 TAPDEBUG("%s%d starting\n", ifp->if_name, ifp->if_unit);
579
580 /*
581 * do not junk pending output if we are in VMnet mode.
582 * XXX: can this do any harm because of queue overflow?
583 */
584
585 if (((tp->tap_flags & TAP_VMNET) == 0) &&
586 ((tp->tap_flags & TAP_READY) != TAP_READY)) {
587 struct mbuf *m = NULL;
588
589 TAPDEBUG("%s%d not ready, tap_flags = 0x%x\n", ifp->if_name,
590 ifp->if_unit, tp->tap_flags);
591
592 s = splimp();
593 do {
594 IF_DEQUEUE(&ifp->if_snd, m);
595 if (m != NULL)
596 m_freem(m);
597 ifp->if_oerrors ++;
--- 34 unchanged lines hidden (view full) ---
632 dev_t dev;
633 u_long cmd;
634 caddr_t data;
635 int flag;
636 struct thread *td;
637{
638 struct tap_softc *tp = dev->si_drv1;
639 struct ifnet *ifp = &tp->tap_if;
640 struct tapinfo *tapp = NULL;
641 int s;
642 int f;
643
644 switch (cmd) {
645 case TAPSIFINFO:
646 s = splimp();
647 tapp = (struct tapinfo *)data;
648 ifp->if_mtu = tapp->mtu;
649 ifp->if_type = tapp->type;
650 ifp->if_baudrate = tapp->baudrate;
651 splx(s);
652 break;
653
654 case TAPGIFINFO:
655 tapp = (struct tapinfo *)data;
656 tapp->mtu = ifp->if_mtu;
657 tapp->type = ifp->if_type;
658 tapp->baudrate = ifp->if_baudrate;
659 break;
660
661 case TAPSDEBUG:
662 tapdebug = *(int *)data;
663 break;
664
665 case TAPGDEBUG:
666 *(int *)data = tapdebug;
667 break;
--- 83 unchanged lines hidden (view full) ---
751 struct uio *uio;
752 int flag;
753{
754 struct tap_softc *tp = dev->si_drv1;
755 struct ifnet *ifp = &tp->tap_if;
756 struct mbuf *m = NULL;
757 int error = 0, len, s;
758
759 TAPDEBUG("%s%d reading, minor = %#x\n",
760 ifp->if_name, ifp->if_unit, minor(dev));
761
762 if ((tp->tap_flags & TAP_READY) != TAP_READY) {
763 TAPDEBUG("%s%d not ready. minor = %#x, tap_flags = 0x%x\n",
764 ifp->if_name, ifp->if_unit, minor(dev), tp->tap_flags);
765
766 return (EHOSTDOWN);
767 }
--- 4 unchanged lines hidden (view full) ---
772 do {
773 s = splimp();
774 IF_DEQUEUE(&ifp->if_snd, m);
775 splx(s);
776
777 if (m == NULL) {
778 if (flag & IO_NDELAY)
779 return (EWOULDBLOCK);
780
781 tp->tap_flags |= TAP_RWAIT;
782 error = tsleep((caddr_t)tp,PCATCH|(PZERO+1),"taprd",0);
783 if (error)
784 return (error);
785 }
786 } while (m == NULL);
787
788 /* feed packet to bpf */
--- 5 unchanged lines hidden (view full) ---
794 if (len == 0)
795 break;
796
797 error = uiomove(mtod(m, void *), len, uio);
798 m = m_free(m);
799 }
800
801 if (m != NULL) {
802 TAPDEBUG("%s%d dropping mbuf, minor = %#x\n", ifp->if_name,
803 ifp->if_unit, minor(dev));
804 m_freem(m);
805 }
806
807 return (error);
808} /* tapread */
809
810
--- 6 unchanged lines hidden (view full) ---
817tapwrite(dev, uio, flag)
818 dev_t dev;
819 struct uio *uio;
820 int flag;
821{
822 struct tap_softc *tp = dev->si_drv1;
823 struct ifnet *ifp = &tp->tap_if;
824 struct mbuf *top = NULL, **mp = NULL, *m = NULL;
825 int error = 0, tlen, mlen;
826
827 TAPDEBUG("%s%d writting, minor = %#x\n",
828 ifp->if_name, ifp->if_unit, minor(dev));
829
830 if (uio->uio_resid == 0)
831 return (0);
832
833 if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) {
834 TAPDEBUG("%s%d invalid packet len = %d, minor = %#x\n",
835 ifp->if_name, ifp->if_unit, uio->uio_resid, minor(dev));
--- 28 unchanged lines hidden (view full) ---
864 ifp->if_ierrors ++;
865 if (top)
866 m_freem(top);
867 return (error);
868 }
869
870 top->m_pkthdr.len = tlen;
871 top->m_pkthdr.rcvif = ifp;
872
873 /* Pass packet up to parent. */
874 (*ifp->if_input)(ifp, top);
875 ifp->if_ipackets ++; /* ibytes are counted in parent */
876
877 return (0);
878} /* tapwrite */
879
880
--- 7 unchanged lines hidden (view full) ---
888static int
889tappoll(dev, events, td)
890 dev_t dev;
891 int events;
892 struct thread *td;
893{
894 struct tap_softc *tp = dev->si_drv1;
895 struct ifnet *ifp = &tp->tap_if;
896 int s, revents = 0;
897
898 TAPDEBUG("%s%d polling, minor = %#x\n",
899 ifp->if_name, ifp->if_unit, minor(dev));
900
901 s = splimp();
902 if (events & (POLLIN | POLLRDNORM)) {
903 if (ifp->if_snd.ifq_len > 0) {
904 TAPDEBUG("%s%d have data in queue. len = %d, " \
905 "minor = %#x\n", ifp->if_name, ifp->if_unit,
906 ifp->if_snd.ifq_len, minor(dev));
--- 16 unchanged lines hidden ---