chiark / gitweb /
server: Correct handling of interface names in tun interface.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 11 Jan 2007 00:04:39 +0000 (00:04 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 11 Jan 2007 00:04:39 +0000 (00:04 +0000)
Now that interface names can be changed, we need to let the tunnel
driver know of changes so that it can produce the right messages when
things go weird.  It's better to let the peer edifice handle interface
names, so

  * let `create' return the interface name rather than have p_ifname ask
    the tunnel explicitly, and

  * replace the `ifname' query with an optional `setifname'
    notification, which is currently used only by the SLIP driver to
    maintain the correct name for its persistent interfaces.

doc/tripe-admin.5.in
server/peer.c
server/tripe.h
server/tun-bsd.c
server/tun-linux.c
server/tun-slip.c
server/tun-unet.c

index 1f52a6db7785ca95637b2ad5c6f5f67222312fa8..94c7c3b8496558fa3afde06f6747c383025a5864 100644 (file)
@@ -1263,7 +1263,7 @@ create some more
 .BI /dev/tun nn
 files, it will work.
 .SP
 .BI /dev/tun nn
 files, it will work.
 .SP
-.BI "TUN - " tun-name " open-error " device " " ecode " " message
+.BI "TUN \- " tun-name " open-error " device " " ecode " " message
 An attempt to open the tunnel device file
 .I device
 failed.
 An attempt to open the tunnel device file
 .I device
 failed.
@@ -1314,10 +1314,6 @@ shouldn't be used any more.
 .BI "TUN \- unet getinfo-error " ecode " " message
 Reading information about the Unet interface failed.  Unet is obsolete
 and shouldn't be used any more.
 .BI "TUN \- unet getinfo-error " ecode " " message
 Reading information about the Unet interface failed.  Unet is obsolete
 and shouldn't be used any more.
-.SP
-.BI "TUN \- unet ifname-too-long"
-The Unet interface's name overflowed, so we couldn't read it properly.
-Unet is obsolete and shouldn't be used any more.
 .SS "USER warnings"
 These are issued by administration clients using the
 .B WARN
 .SS "USER warnings"
 These are issued by administration clients using the
 .B WARN
index c9198924327c9068d7c0cbc42e4dec91673b6dfb..fd79a84c5ef59094c672dab9a78d0cfab57b4132 100644 (file)
@@ -567,7 +567,12 @@ const char *p_ifname(peer *p) { return (p->ifname); }
  */
 
 void p_setifname(peer *p, const char *name)
  */
 
 void p_setifname(peer *p, const char *name)
-  { if (p->ifname) xfree(p->ifname); p->ifname = xstrdup(name); }
+{
+  xfree(p->ifname);
+  p->ifname = xstrdup(name);
+  if (p->spec.tops->setifname)
+    p->spec.tops->setifname(p->t, name);
+}
 
 /* --- @p_addr@ --- *
  *
 
 /* --- @p_addr@ --- *
  *
@@ -700,12 +705,11 @@ peer *p_create(peerspec *spec)
   p->ifname = 0;
   memset(&p->st, 0, sizeof(stats));
   p->st.t_start = time(0);
   p->ifname = 0;
   memset(&p->st, 0, sizeof(stats));
   p->st.t_start = time(0);
-  if ((p->t = spec->tops->create(p)) == 0)
+  if ((p->t = spec->tops->create(p, &p->ifname)) == 0)
     goto tidy_0;
   p_setkatimer(p);
   if (kx_init(&p->kx, p, &p->ks))
     goto tidy_1;
     goto tidy_0;
   p_setkatimer(p);
   if (kx_init(&p->kx, p, &p->ks))
     goto tidy_1;
-  p_setifname(p, spec->tops->ifname(p->t));
   p->next = peers;
   if (peers)
     peers->prev = p;
   p->next = peers;
   if (peers)
     peers->prev = p;
@@ -722,6 +726,7 @@ peer *p_create(peerspec *spec)
 tidy_1:
   if (spec->t_ka)
     sel_rmtimer(&p->tka);
 tidy_1:
   if (spec->t_ka)
     sel_rmtimer(&p->tka);
+  xfree(p->ifname);
   p->t->ops->destroy(p->t);
 tidy_0:
   xfree(p->spec.name);
   p->t->ops->destroy(p->t);
 tidy_0:
   xfree(p->spec.name);
@@ -788,7 +793,6 @@ void p_destroy(peer *p)
   p->t->ops->destroy(p->t);
   if (p->spec.t_ka)
     sel_rmtimer(&p->tka);
   p->t->ops->destroy(p->t);
   if (p->spec.t_ka)
     sel_rmtimer(&p->tka);
-  xfree(p->spec.name);
   for (pg = p->pings; pg; pg = ppg) {
     ppg = pg->next;
     p_pingdone(pg, PING_PEERDIED);
   for (pg = p->pings; pg; pg = ppg) {
     ppg = pg->next;
     p_pingdone(pg, PING_PEERDIED);
index 66fb091d3e5f253a095a2184c4efebcd23cf2b99..5f00718db5ecdd40b7bb195893e8d06b4fb37477 100644 (file)
@@ -269,8 +269,10 @@ struct peer;
 typedef struct tunnel_ops {
   const char *name;                    /* Name of this tunnel driver */
   void (*init)(void);                  /* Initializes the system */
 typedef struct tunnel_ops {
   const char *name;                    /* Name of this tunnel driver */
   void (*init)(void);                  /* Initializes the system */
-  tunnel *(*create)(struct peer */*p*/); /* Initializes a new tunnel */
-  const char *(*ifname)(tunnel */*t*/);        /* Returns tunnel's interface name */
+  tunnel *(*create)(struct peer */*p*/, char **/*ifn*/);
+                                       /* Initializes a new tunnel */
+  void (*setifname)(tunnel */*t*/, const char */*ifn*/);
+                                       /*  Notifies ifname change */
   void (*inject)(tunnel */*t*/, buf */*b*/); /* Sends packet through if */
   void (*destroy)(tunnel */*t*/);      /* Destroys a tunnel */
 } tunnel_ops;
   void (*inject)(tunnel */*t*/, buf */*b*/); /* Sends packet through if */
   void (*destroy)(tunnel */*t*/);      /* Destroys a tunnel */
 } tunnel_ops;
index 4e8c0bd82a6ba0d0a30fc5d3296f72aae7382e3c..cf6c6d02518a84a2b2985ba5101005c5df93fcd5 100644 (file)
@@ -43,20 +43,6 @@ struct tunnel {
   unsigned n;                          /* Number of my tunnel device */
 };  
 
   unsigned n;                          /* Number of my tunnel device */
 };  
 
-/* --- @t_ifname@ --- *
- *
- * Arguments:  @tunnel *t@ = pointer to tunnel block
- *
- * Returns:    A pointer to the tunnel's interface name.
- */
-
-static const char *t_ifname(tunnel *t)
-{
-  static char buf[8];
-  sprintf(buf, "tun%u", t->n);
-  return (buf);
-}
-
 /* --- @t_read@ --- *
  *
  * Arguments:  @int fd@ = file descriptor to read
 /* --- @t_read@ --- *
  *
  * Arguments:  @int fd@ = file descriptor to read
@@ -76,7 +62,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN", "%s", t_ifname(t), "read-error", "?ERRNO", A_END);
+    a_warn("TUN", "%s", p_ifname(t->p), "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -102,13 +88,14 @@ static void t_init(void) { return; }
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
+ *             @char **ifn@ = where to put the interface name
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   int fd;
   unsigned n;
 {
   int fd;
   unsigned n;
@@ -141,8 +128,9 @@ static tunnel *t_create(peer *p)
   t->n = n;
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   t->n = n;
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
+  *ifn = xstrdup(buf + 5);
   T( trace(T_TUNNEL, "tun-bsd: attached interface %s to peer `%s'",
   T( trace(T_TUNNEL, "tun-bsd: attached interface %s to peer `%s'",
-          t_ifname(t), p_name(p)); )
+          *ifn, p_name(p)); )
   return (t);
 }
 
   return (t);
 }
 
@@ -185,7 +173,7 @@ const tunnel_ops tun_bsd = {
   "bsd",
   t_init,
   t_create,
   "bsd",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };
   t_inject,
   t_destroy
 };
index 3cfa5d72d03778362fc59eef55163f606e7d8b04..42503548b94ee2bfdf7085fbb3de9769effd1ff1 100644 (file)
@@ -46,7 +46,6 @@ struct tunnel {
   const tunnel_ops *ops;               /* Pointer to operations */
   sel_file f;                          /* Selector for TUN/TAP device */
   struct peer *p;                      /* Pointer to my peer */
   const tunnel_ops *ops;               /* Pointer to operations */
   sel_file f;                          /* Selector for TUN/TAP device */
   struct peer *p;                      /* Pointer to my peer */
-  char ifn[IFNAMSIZ];                  /* Interface name buffer */
 };  
 
 /* --- @t_read@ --- *
 };  
 
 /* --- @t_read@ --- *
@@ -68,7 +67,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN", "%s", t->ifn, "read-error", "?ERRNO", A_END);
+    a_warn("TUN", "%s", p_ifname(t->p), "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -94,13 +93,14 @@ static void t_init(void) { return; }
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
+ *             @char **ifn@ = where to put the interface name
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   int fd;
   int f;
 {
   int fd;
   int f;
@@ -128,21 +128,12 @@ static tunnel *t_create(peer *p)
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   iff.ifr_name[IFNAMSIZ - 1] = 0;
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   iff.ifr_name[IFNAMSIZ - 1] = 0;
-  strcpy(t->ifn, iff.ifr_name);
+  *ifn = xstrdup(iff.ifr_name);
   T( trace(T_TUNNEL, "tun-linux: attached interface %s to peer `%s'",
   T( trace(T_TUNNEL, "tun-linux: attached interface %s to peer `%s'",
-          t->ifn, p_name(p)); )
+          *ifn, p_name(p)); )
   return (t);
 }
 
   return (t);
 }
 
-/* --- @t_ifname@ --- *
- *
- * Arguments:  @tunnel *t@ = pointer to tunnel block
- *
- * Returns:    A pointer to the tunnel's interface name.
- */
-
-static const char *t_ifname(tunnel *t) { return (t->ifn); }
-
 /* --- @t_inject@ --- *
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
 /* --- @t_inject@ --- *
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
@@ -182,7 +173,7 @@ const tunnel_ops tun_linux = {
   "linux",
   t_init,
   t_create,
   "linux",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };
   t_inject,
   t_destroy
 };
index 2efda8900e03be73b5a344ee6c553490f3740a07..0df028e49365710c7053db8f9800f00b482f3d69 100644 (file)
@@ -100,11 +100,11 @@ static void t_read(int fd, unsigned mode, void *v)
 #endif
        errno == EAGAIN)
       return;
 #endif
        errno == EAGAIN)
       return;
-    a_warn("TUN", "%s", t->sl->name, "read-error", "?ERRNO", A_END);
+    a_warn("TUN", "%s", p_ifname(t->p), "read-error", "?ERRNO", A_END);
     return;
   }
   if (!n) {
     return;
   }
   if (!n) {
-    a_warn("TUN", "%s", t->sl->name, "slip", "eof", A_END);
+    a_warn("TUN", "%s", p_ifname(t->p), "slip", "eof", A_END);
     t->st = ST_EOF;
     sel_rmfile(&t->f);
     return;
     t->st = ST_EOF;
     sel_rmfile(&t->f);
     return;
@@ -126,7 +126,7 @@ static void t_read(int fd, unsigned mode, void *v)
        if (st & ST_BAD)
          ;
        else if (st & ST_ESC)
        if (st & ST_BAD)
          ;
        else if (st & ST_ESC)
-         a_warn("TUN", "%s", t->sl->name, "slip", "escape-end", A_END);
+         a_warn("TUN", "%s", p_ifname(t->p), "slip", "escape-end", A_END);
        else if (q == t->buf) {
          T( trace(T_TUNNEL, "tun-slip: empty packet"); )
        } else {
        else if (q == t->buf) {
          T( trace(T_TUNNEL, "tun-slip: empty packet"); )
        } else {
@@ -143,7 +143,7 @@ static void t_read(int fd, unsigned mode, void *v)
        break;
       case SL_ESC:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
        break;
       case SL_ESC:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
-         a_warn("TUN", "%s", t->sl->name, "slip", "bad-escape", A_END);
+         a_warn("TUN", "%s", p_ifname(t->p), "slip", "bad-escape", A_END);
          st |= ST_BAD;
        } else
          st |= ST_ESC;
          st |= ST_BAD;
        } else
          st |= ST_ESC;
@@ -158,7 +158,7 @@ static void t_read(int fd, unsigned mode, void *v)
        goto emit;
       default:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
        goto emit;
       default:
        if ((st & ST_ESC) && !(st & ST_BAD)) {
-         a_warn("TUN", "%s", t->sl->name, "slip", "bad-escape", A_END);
+         a_warn("TUN", "%s", p_ifname(t->p), "slip", "bad-escape", A_END);
          st |= ST_BAD;
        }
       emit:
          st |= ST_BAD;
        }
       emit:
@@ -166,7 +166,7 @@ static void t_read(int fd, unsigned mode, void *v)
          if (q < ll)
            *q++ = o;
          else {
          if (q < ll)
            *q++ = o;
          else {
-           a_warn("TUN", "%s", t->sl->name, "slip", "overflow", A_END);
+           a_warn("TUN", "%s", p_ifname(t->p), "slip", "overflow", A_END);
            st |= ST_BAD;
          }
        }
            st |= ST_BAD;
          }
        }
@@ -253,13 +253,14 @@ whine:
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
 /* --- @t_create@ --- *
  *
  * Arguments:  @peer *p@ = pointer to peer block
+ *             @char **ifn@ = where to put the interface name
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   slipif *sl = 0;
   int pin[2] = { -1, -1 }, pout[2] = { -1, -1 };
 {
   slipif *sl = 0;
   int pin[2] = { -1, -1 }, pout[2] = { -1, -1 };
@@ -345,6 +346,7 @@ found:
   sel_initfile(&sel, &t->f, sl->ifd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   write(sl->ofd, end, sizeof(end));
   sel_initfile(&sel, &t->f, sl->ifd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   write(sl->ofd, end, sizeof(end));
+  *ifn = xstrdup(sl->name);
   dstr_destroy(&d);
   return (t);
 
   dstr_destroy(&d);
   return (t);
 
@@ -361,14 +363,18 @@ fail:
   return (0);
 }
 
   return (0);
 }
 
-/* --- @t_ifname@ --- *
+/* --- @t_setifname@ --- *
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
+ *             @const char *ifn@ = new interface name
  *
  *
- * Returns:    A pointer to the tunnel's interface name.
+ * Returns:    ---
+ *
+ * Use:                Updates the interface name of a slip interface.
  */
 
  */
 
-static const char *t_ifname(tunnel *t) { return (t->sl->name); }
+static void t_setifname(tunnel *t, const char *ifn)
+  { xfree(t->sl->name); t->sl->name = xstrdup(ifn); }
 
 /* --- @t_inject@ --- *
  *
 
 /* --- @t_inject@ --- *
  *
@@ -442,7 +448,7 @@ const tunnel_ops tun_slip = {
   "slip",
   t_init,
   t_create,
   "slip",
   t_init,
   t_create,
-  t_ifname,
+  t_setifname,
   t_inject,
   t_destroy
 };
   t_inject,
   t_destroy
 };
index c2b6e7710cef1a97a96b5ecf7993eb2cb77d0fc7..bdf23fe4454066dc0e08e96c41016f881521018f 100644 (file)
@@ -48,29 +48,6 @@ struct tunnel {
   struct peer *p;                      /* Pointer to my peer */
 };
 
   struct peer *p;                      /* Pointer to my peer */
 };
 
-/* --- @t_ifname@ --- *
- *
- * Arguments:  @tunnel *t@ = pointer to tunnel block
- *
- * Returns:    A pointer to the tunnel's interface name.
- */
-
-static const char *t_ifname(tunnel *t)
-{
-  static char b[UNET_NAMEMAX];
-  struct unet_info uni;
-  if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
-    a_warn("TUN", "-", "unet", "getinfo-error", "?ERRNO", A_END);
-    return ("<error>");
-  }
-  if (strlen(uni.uni_ifname) + 1 > sizeof(b)) {
-    a_warn("TUN", "-", "unet", "ifname-too-long", A_END);
-    return ("<error>");
-  }
-  strcpy(b, uni.uni_ifname);
-  return (b);
-}
-
 /* --- @t_read@ --- *
  *
  * Arguments:  @int fd@ = file descriptor to read
 /* --- @t_read@ --- *
  *
  * Arguments:  @int fd@ = file descriptor to read
@@ -90,7 +67,7 @@ static void t_read(int fd, unsigned mode, void *v)
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
 
   n = read(fd, buf_i, sizeof(buf_i));
   if (n < 0) {
-    a_warn("TUN", "%s", t_ifname(t), "read-error", "?ERRNO", A_END);
+    a_warn("TUN", "%s", p_ifname(t->p), "read-error", "?ERRNO", A_END);
     return;
   }
   IF_TRACING(T_TUNNEL, {
     return;
   }
   IF_TRACING(T_TUNNEL, {
@@ -117,17 +94,19 @@ static void t_init(void) { return; }
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
  *             @peer *p@ = pointer to peer block
  *
  * Arguments:  @tunnel *t@ = pointer to tunnel block
  *             @peer *p@ = pointer to peer block
+ *             @char *ifn@ = where to put the interface name
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
  *
  * Returns:    A tunnel block if it worked, or null on failure.
  *
  * Use:                Initializes a new tunnel.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   int fd;
   tunnel *t;
   int f;
 {
   int fd;
   tunnel *t;
   int f;
+  struct unet_info uni;
 
   if ((fd = open("/dev/unet", O_RDWR)) < 0) {
     a_warn("TUN", "-", "unet", "open-error", "/dev/unet", "?ERRNO", A_END);
 
   if ((fd = open("/dev/unet", O_RDWR)) < 0) {
     a_warn("TUN", "-", "unet", "open-error", "/dev/unet", "?ERRNO", A_END);
@@ -145,8 +124,14 @@ static tunnel *t_create(peer *p)
   t->p = p;
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
   t->p = p;
   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
   sel_addfile(&t->f);
+
+  if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
+    a_warn("TUN", "-", "unet", "getinfo-error", "?ERRNO", A_END);
+    return ("<error>");
+  }
+  *ifn = xstrdup(uni.uni_ifname);
   T( trace(T_TUNNEL, "tun-unet: attached interface %s to peer `%s'",
   T( trace(T_TUNNEL, "tun-unet: attached interface %s to peer `%s'",
-          t_ifname(t), p_name(p)); )
+          *ifn, p_name(p)); )
   return (t);
 }
 
   return (t);
 }
 
@@ -189,7 +174,7 @@ const tunnel_ops tun_unet = {
   "unet",
   t_init,
   t_create,
   "unet",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };
   t_inject,
   t_destroy
 };