Extract Subversion ignore data.
[unet] / unet.c
diff --git a/unet.c b/unet.c
index 09020eb..3761138 100644 (file)
--- a/unet.c
+++ b/unet.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: unet.c,v 1.1 2001/01/25 22:03:39 mdw Exp $
+ * $Id: unet.c,v 1.3 2001/02/19 19:10:28 mdw Exp $
  *
  * User-space network device support.
  *
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: unet.c,v $
+ * Revision 1.3  2001/02/19 19:10:28  mdw
+ * New option to allow changing interface flags.
+ *
+ * Revision 1.2  2001/02/03 18:39:59  mdw
+ * Setting the maximum interface count now does the right thing.
+ *
  * Revision 1.1  2001/01/25 22:03:39  mdw
  * Initial check-in (somewhat belated).
  *
@@ -122,6 +128,7 @@ static int unet_npersist = UNET_NPERSIST;
 static int unet_maxif = UNET_MAXIF;
 static struct unet *unet_persistent;
 static struct unet *unet_list = 0;
+static int unet_nif = 0;
 
 MODULE_PARM(unet_npersist, "i");
 MODULE_PARM(unet_maxif, "i");
@@ -373,7 +380,7 @@ static int unet_ifinit(struct device *nif)
   u->nif.rebuild_header = 0;
   u->nif.set_mac_address = 0;
 
-  u->nif.type = ARPHRD_LOOPBACK;       /* Got a better idea? */
+  u->nif.type = ARPHRD_TUNNEL;         /* Got a better idea? */
   u->nif.hard_header_len = 0;
   u->nif.mtu = 1500 - MAX_HEADER;
   u->nif.addr_len = 0;
@@ -519,21 +526,20 @@ static int unet_devopen(struct inode *ino, struct file *f)
 
   /* --- Otherwise we've got to create a new one --- */
 
-  else {
+  else if (seq == UNET_TRANSMINOR) {
 
     /* --- Try to find a spare sequence number --- */
 
+    if (unet_nif >= unet_maxif) {
+      printk(KERN_NOTICE "unet: no interfaces left\n");
+      e = -ENFILE;
+      goto tidy_0;
+    }
     for (seq = unet_npersist, up = &unet_list; *up != 0;
         seq++, up = &(*up)->next) {
       if ((*up)->seq > seq)
        break;
-      if (seq >= unet_maxif) {
-       printk("unet: all unets are occupied\n");
-       e = -ENFILE;
-       goto tidy_0;
-      }
     }
-
     D( printk(KERN_DEBUG "unet: allocated sequence number %d\n", seq); )
 
     /* --- Allocate a new block --- */
@@ -549,6 +555,7 @@ static int unet_devopen(struct inode *ino, struct file *f)
     if ((e = unet_setup(u, seq)) != 0)
       goto tidy_1;
     u->f |= UNIF_TRANS;
+    unet_nif++;
 
     /* --- Link the block into the list --- */
 
@@ -560,7 +567,8 @@ static int unet_devopen(struct inode *ino, struct file *f)
 
     D( printk(KERN_DEBUG "unet: opened transient %d\n", seq);
        unet_dumpBlock(u); )
-  }
+  } else
+    return (-ENODEV);
 
   /* --- Done --- */
 
@@ -596,12 +604,14 @@ static int unet_devclose(struct inode *ino, struct file *f)
   /* --- A transient unet needs to be destroyed --- */
 
   if (u->f & UNIF_TRANS) {
+    int seq = u->seq;
     *u->prev = u->next;
     if (u->next)
       u->next->prev = u->prev;
     unet_kill(u);
     kfree(u);
-    D( printk(KERN_DEBUG "unet: released transient unet\n"); )
+    unet_nif--;
+    D( printk(KERN_DEBUG "unet: released transient %d\n", seq); )
   }
 
   /* --- A persistent unet needs to be shutdown --- */
@@ -863,6 +873,8 @@ static int unet_devioctl(struct inode *ino,
       int n = !!arg;
       int o = !!(u->f & UNIF_DEBUG);
 
+      if (!capable(CAP_SYS_ADMIN))
+       return (-EPERM);
       if (n || o) {
        printk(KERN_DEBUG "unet: UNIOCSDEBUG on %s: %s\n", u->name,
               (o && n) ? "debugging still on" :
@@ -906,12 +918,16 @@ static int unet_devioctl(struct inode *ino,
 
 #if UNET_DEBUG == UNET_DEBUGRUNTIME
     case UNIOCSGDEBUG:
-      printk(KERN_DEBUG "unet: UNIOCSGDEBUG: set global debug: %s\n",
-            (arg && unet_debug) ? "debugging still on" :
-             (!arg && unet_debug) ? "debugging turned off" :
-            (arg && !unet_debug) ? "debugging turned on" :
-            (!arg && !unet_debug) ? "you can't see this message" :
-            "Logic failure: universe exploding");
+      if (!capable(CAP_SYS_ADMIN))
+       return (-EPERM);
+      if (arg || unet_debug) {
+       printk(KERN_DEBUG "unet: UNIOCSGDEBUG: set global debug: %s\n",
+              (arg && unet_debug) ? "debugging still on" :
+              (!arg && unet_debug) ? "debugging turned off" :
+              (arg && !unet_debug) ? "debugging turned on" :
+              (!arg && !unet_debug) ? "you can't see this message" :
+              "Logic failure: universe exploding");
+      }
       unet_debug = !!arg;
       break;
 #endif
@@ -935,18 +951,34 @@ static int unet_devioctl(struct inode *ino,
     /* --- @UNIOCSMAXIF@ --- */
 
     case UNIOCSMAXIF:
-      e = -EINVAL;
+      if (!capable(CAP_SYS_ADMIN))
+       return (-EPERM);
+      D( printk(KERN_DEBUG "unet: UNIOCSMAXIF: "
+               "arg = %ld; npersist = %d; nif = %d\n",
+               arg, unet_npersist, unet_nif); )
       if (arg < unet_npersist || arg > INT_MAX)
        return (-EINVAL);
-      for (u = unet_list; u; u = u->next) {
-       if (u->seq >= unet_npersist)
-         return (-EBUSY);
-      }
+      if (arg < unet_nif)
+       return (-EBUSY);
       unet_maxif = arg;
-      D( printk(KERN_DEBUG "unet: UNIOCSMAXIF: unet_maxif = %d\n",
+      e = 0;
+      D( printk(KERN_DEBUG "unet: UNIOCSMAXIF: set unet_maxif = %d\n",
                unet_maxif); )
       break;
 
+    /* --- @UNIOCFIFFLAGS@ and @UNIOCSIFFLAGS@ --- */
+
+    case UNIOCGIFFLAGS:
+      D( printk(KERN_DEBUG "unet: UNIOCGIFFFLAGS\n"); )
+      e = u->nif.flags;
+      break;
+    case UNIOCSIFFLAGS:
+      D( printk(KERN_DEBUG "unet: UNIOCSIFFFLAGS: arg = %ld\n", arg); )
+      if ((u->nif.flags ^ arg) & ~IFF_VOLATILE)
+       return (-EINVAL);
+      u->nif.flags = arg;
+      break;
+
     /* --- Everything else --- *
      *
      * You lose.
@@ -1016,6 +1048,7 @@ __initfunc(int unet_init(void))
       goto tidy_2;
     }
   }
+  unet_nif = unet_npersist;
 
   /* --- Done --- */