[BACK]Return to if_tap.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / net

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/net/if_tap.c between version 1.47 and 1.47.4.6

version 1.47, 2008/08/26 11:06:59 version 1.47.4.6, 2009/04/04 23:36:28
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*  /*
  *  Copyright (c) 2003, 2004, 2008 The NetBSD Foundation.   *  Copyright (c) 2003, 2004, 2008, 2009 The NetBSD Foundation.
  *  All rights reserved.   *  All rights reserved.
  *   *
  *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
Line 37  __KERNEL_RCSID(0, "$NetBSD$");
Line 37  __KERNEL_RCSID(0, "$NetBSD$");
   
 #if defined(_KERNEL_OPT)  #if defined(_KERNEL_OPT)
 #include "bpfilter.h"  #include "bpfilter.h"
   #include "opt_modular.h"
   #include "opt_compat_netbsd.h"
 #endif  #endif
   
 #include <sys/param.h>  #include <sys/param.h>
Line 49  __KERNEL_RCSID(0, "$NetBSD$");
Line 51  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/filedesc.h>  #include <sys/filedesc.h>
 #include <sys/ksyms.h>  #include <sys/ksyms.h>
 #include <sys/poll.h>  #include <sys/poll.h>
   #include <sys/proc.h>
 #include <sys/select.h>  #include <sys/select.h>
 #include <sys/sockio.h>  #include <sys/sockio.h>
   #if defined(COMPAT_40) || defined(MODULAR)
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   #endif
 #include <sys/kauth.h>  #include <sys/kauth.h>
 #include <sys/mutex.h>  #include <sys/mutex.h>
 #include <sys/simplelock.h>  #include <sys/simplelock.h>
Line 68  __KERNEL_RCSID(0, "$NetBSD$");
Line 73  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <compat/sys/sockio.h>  #include <compat/sys/sockio.h>
   
   #if defined(COMPAT_40) || defined(MODULAR)
 /*  /*
  * sysctl node management   * sysctl node management
  *   *
Line 85  __KERNEL_RCSID(0, "$NetBSD$");
Line 91  __KERNEL_RCSID(0, "$NetBSD$");
 static int tap_node;  static int tap_node;
 static int      tap_sysctl_handler(SYSCTLFN_PROTO);  static int      tap_sysctl_handler(SYSCTLFN_PROTO);
 SYSCTL_SETUP_PROTO(sysctl_tap_setup);  SYSCTL_SETUP_PROTO(sysctl_tap_setup);
   #endif
   
 /*  /*
  * Since we're an Ethernet device, we need the 3 following   * Since we're an Ethernet device, we need the 3 following
Line 141  static int tap_fops_poll(file_t *, int);
Line 148  static int tap_fops_poll(file_t *, int);
 static int      tap_fops_kqfilter(file_t *, struct knote *);  static int      tap_fops_kqfilter(file_t *, struct knote *);
   
 static const struct fileops tap_fileops = {  static const struct fileops tap_fileops = {
         tap_fops_read,          .fo_read = tap_fops_read,
         tap_fops_write,          .fo_write = tap_fops_write,
         tap_fops_ioctl,          .fo_ioctl = tap_fops_ioctl,
         fnullop_fcntl,          .fo_fcntl = fnullop_fcntl,
         tap_fops_poll,          .fo_poll = tap_fops_poll,
         fbadop_stat,          .fo_stat = fbadop_stat,
         tap_fops_close,          .fo_close = tap_fops_close,
         tap_fops_kqfilter,          .fo_kqfilter = tap_fops_kqfilter,
           .fo_drain = fnullop_drain,
 };  };
   
 /* Helper for cloning open() */  /* Helper for cloning open() */
Line 197  static int tap_init(struct ifnet *);
Line 205  static int tap_init(struct ifnet *);
 static int      tap_ioctl(struct ifnet *, u_long, void *);  static int      tap_ioctl(struct ifnet *, u_long, void *);
   
 /* Internal functions */  /* Internal functions */
   #if defined(COMPAT_40) || defined(MODULAR)
 static int      tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *);  static int      tap_lifaddr(struct ifnet *, u_long, struct ifaliasreq *);
   #endif
 static void     tap_softintr(void *);  static void     tap_softintr(void *);
   
 /*  /*
Line 246  tap_attach(device_t parent, device_t sel
Line 256  tap_attach(device_t parent, device_t sel
 {  {
         struct tap_softc *sc = device_private(self);          struct tap_softc *sc = device_private(self);
         struct ifnet *ifp;          struct ifnet *ifp;
   #if defined(COMPAT_40) || defined(MODULAR)
         const struct sysctlnode *node;          const struct sysctlnode *node;
           int error;
   #endif
         uint8_t enaddr[ETHER_ADDR_LEN] =          uint8_t enaddr[ETHER_ADDR_LEN] =
             { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };              { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
         char enaddrstr[3 * ETHER_ADDR_LEN];          char enaddrstr[3 * ETHER_ADDR_LEN];
         struct timeval tv;          struct timeval tv;
         uint32_t ui;          uint32_t ui;
         int error;  
   
         sc->sc_dev = self;          sc->sc_dev = self;
         sc->sc_sih = softint_establish(SOFTINT_CLOCK, tap_softintr, sc);          sc->sc_sih = softint_establish(SOFTINT_CLOCK, tap_softintr, sc);
   
           if (!pmf_device_register(self, NULL, NULL))
                   aprint_error_dev(self, "couldn't establish power handler\n");
   
         /*          /*
          * In order to obtain unique initial Ethernet address on a host,           * In order to obtain unique initial Ethernet address on a host,
          * do some randomisation using the current uptime.  It's not meant           * do some randomisation using the current uptime.  It's not meant
Line 309  tap_attach(device_t parent, device_t sel
Line 324  tap_attach(device_t parent, device_t sel
   
         sc->sc_flags = 0;          sc->sc_flags = 0;
   
   #if defined(COMPAT_40) || defined(MODULAR)
         /*          /*
          * Add a sysctl node for that interface.           * Add a sysctl node for that interface.
          *           *
Line 331  tap_attach(device_t parent, device_t sel
Line 347  tap_attach(device_t parent, device_t sel
             CTL_EOL)) != 0)              CTL_EOL)) != 0)
                 aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n",                  aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n",
                     error);                      error);
   #endif
   
         /*          /*
          * Initialize the two locks for the device.           * Initialize the two locks for the device.
Line 362  tap_detach(device_t self, int flags)
Line 379  tap_detach(device_t self, int flags)
 {  {
         struct tap_softc *sc = device_private(self);          struct tap_softc *sc = device_private(self);
         struct ifnet *ifp = &sc->sc_ec.ec_if;          struct ifnet *ifp = &sc->sc_ec.ec_if;
         int error, s;  #if defined(COMPAT_40) || defined(MODULAR)
           int error;
   #endif
           int s;
   
         sc->sc_flags |= TAP_GOING;          sc->sc_flags |= TAP_GOING;
         s = splnet();          s = splnet();
Line 372  tap_detach(device_t self, int flags)
Line 392  tap_detach(device_t self, int flags)
   
         softint_disestablish(sc->sc_sih);          softint_disestablish(sc->sc_sih);
   
   #if defined(COMPAT_40) || defined(MODULAR)
         /*          /*
          * Destroying a single leaf is a very straightforward operation using           * Destroying a single leaf is a very straightforward operation using
          * sysctl_destroyv.  One should be sure to always end the path with           * sysctl_destroyv.  One should be sure to always end the path with
Line 381  tap_detach(device_t self, int flags)
Line 402  tap_detach(device_t self, int flags)
             device_unit(sc->sc_dev), CTL_EOL)) != 0)              device_unit(sc->sc_dev), CTL_EOL)) != 0)
                 aprint_error_dev(self,                  aprint_error_dev(self,
                     "sysctl_destroyv returned %d, ignoring\n", error);                      "sysctl_destroyv returned %d, ignoring\n", error);
   #endif
         ether_ifdetach(ifp);          ether_ifdetach(ifp);
         if_detach(ifp);          if_detach(ifp);
         ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY);          ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY);
         seldestroy(&sc->sc_rsel);          seldestroy(&sc->sc_rsel);
         mutex_destroy(&sc->sc_rdlock);          mutex_destroy(&sc->sc_rdlock);
   
           pmf_device_deregister(self);
   
         return (0);          return (0);
 }  }
   
Line 516  tap_ioctl(struct ifnet *ifp, u_long cmd,
Line 540  tap_ioctl(struct ifnet *ifp, u_long cmd,
         case SIOCGIFMEDIA:          case SIOCGIFMEDIA:
                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd);                  error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd);
                 break;                  break;
   #if defined(COMPAT_40) || defined(MODULAR)
         case SIOCSIFPHYADDR:          case SIOCSIFPHYADDR:
                 error = tap_lifaddr(ifp, cmd, (struct ifaliasreq *)data);                  error = tap_lifaddr(ifp, cmd, (struct ifaliasreq *)data);
                 break;                  break;
   #endif
         default:          default:
                 error = ether_ioctl(ifp, cmd, data);                  error = ether_ioctl(ifp, cmd, data);
                 if (error == ENETRESET)                  if (error == ENETRESET)
Line 531  tap_ioctl(struct ifnet *ifp, u_long cmd,
Line 557  tap_ioctl(struct ifnet *ifp, u_long cmd,
         return (error);          return (error);
 }  }
   
   #if defined(COMPAT_40) || defined(MODULAR)
 /*  /*
  * Helper function to set Ethernet address.  This shouldn't be done there,   * Helper function to set Ethernet address.  This has been replaced by
  * and should actually be available to all Ethernet drivers, real or not.   * the generic SIOCALIFADDR ioctl on a PF_LINK socket.
  */   */
 static int  static int
 tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra)  tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra)
 {  {
         const struct sockaddr_dl *sdl = satosdl(&ifra->ifra_addr);          const struct sockaddr *sa = &ifra->ifra_addr;
   
         if (sdl->sdl_family != AF_LINK)          if (sa->sa_family != AF_LINK)
                 return (EINVAL);                  return (EINVAL);
   
         if_set_sadl(ifp, CLLADDR(sdl), ETHER_ADDR_LEN);          if_set_sadl(ifp, sa->sa_data, ETHER_ADDR_LEN);
   
         return (0);          return (0);
 }  }
   #endif
   
 /*  /*
  * _init() would typically be called when an interface goes up,   * _init() would typically be called when an interface goes up,
Line 880  tap_dev_read(int unit, struct uio *uio, 
Line 908  tap_dev_read(int unit, struct uio *uio, 
         s = splnet();          s = splnet();
         if (IFQ_IS_EMPTY(&ifp->if_snd)) {          if (IFQ_IS_EMPTY(&ifp->if_snd)) {
                 ifp->if_flags &= ~IFF_OACTIVE;                  ifp->if_flags &= ~IFF_OACTIVE;
                 splx(s);  
                 /*                  /*
                  * We must release the lock before sleeping, and re-acquire it                   * We must release the lock before sleeping, and re-acquire it
                  * after.                   * after.
Line 890  tap_dev_read(int unit, struct uio *uio, 
Line 917  tap_dev_read(int unit, struct uio *uio, 
                         error = EWOULDBLOCK;                          error = EWOULDBLOCK;
                 else                  else
                         error = tsleep(sc, PSOCK|PCATCH, "tap", 0);                          error = tsleep(sc, PSOCK|PCATCH, "tap", 0);
                   splx(s);
   
                 if (error != 0)                  if (error != 0)
                         return (error);                          return (error);
                 /* The device might have been downed */                  /* The device might have been downed */
Line 1212  tap_kqread(struct knote *kn, long hint)
Line 1241  tap_kqread(struct knote *kn, long hint)
         return rv;          return rv;
 }  }
   
   #if defined(COMPAT_40) || defined(MODULAR)
 /*  /*
  * sysctl management routines   * sysctl management routines
  * You can set the address of an interface through:   * You can set the address of an interface through:
Line 1342  tap_sysctl_handler(SYSCTLFN_ARGS)
Line 1372  tap_sysctl_handler(SYSCTLFN_ARGS)
         if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN);          if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN);
         return (error);          return (error);
 }  }
   #endif

Legend:
Removed from v.1.47  
changed lines
  Added in v.1.47.4.6

CVSweb <webmaster@jp.NetBSD.org>