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 1f52a6d..94c7c3b 100644 (file)
@@ -1263,7 +1263,7 @@ create some more
 .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.
@@ -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.
-.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
index c919892..fd79a84 100644 (file)
@@ -567,7 +567,12 @@ const char *p_ifname(peer *p) { return (p->ifname); }
  */
 
 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@ --- *
  *
@@ -700,12 +705,11 @@ peer *p_create(peerspec *spec)
   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;
-  p_setifname(p, spec->tops->ifname(p->t));
   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);
+  xfree(p->ifname);
   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);
-  xfree(p->spec.name);
   for (pg = p->pings; pg; pg = ppg) {
     ppg = pg->next;
     p_pingdone(pg, PING_PEERDIED);
index 66fb091..5f00718 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 */
-  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;
index 4e8c0bd..cf6c6d0 100644 (file)
@@ -43,20 +43,6 @@ struct tunnel {
   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
@@ -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) {
-    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, {
@@ -102,13 +88,14 @@ static void t_init(void) { return; }
 /* --- @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.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   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);
+  *ifn = xstrdup(buf + 5);
   T( trace(T_TUNNEL, "tun-bsd: attached interface %s to peer `%s'",
-          t_ifname(t), p_name(p)); )
+          *ifn, p_name(p)); )
   return (t);
 }
 
@@ -185,7 +173,7 @@ const tunnel_ops tun_bsd = {
   "bsd",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };
index 3cfa5d7..4250354 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 */
-  char ifn[IFNAMSIZ];                  /* Interface name buffer */
 };  
 
 /* --- @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) {
-    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, {
@@ -94,13 +93,14 @@ static void t_init(void) { return; }
 /* --- @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.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   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;
-  strcpy(t->ifn, iff.ifr_name);
+  *ifn = xstrdup(iff.ifr_name);
   T( trace(T_TUNNEL, "tun-linux: attached interface %s to peer `%s'",
-          t->ifn, p_name(p)); )
+          *ifn, p_name(p)); )
   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
@@ -182,7 +173,7 @@ const tunnel_ops tun_linux = {
   "linux",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };
index 2efda89..0df028e 100644 (file)
@@ -100,11 +100,11 @@ static void t_read(int fd, unsigned mode, void *v)
 #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) {
-    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;
@@ -126,7 +126,7 @@ static void t_read(int fd, unsigned mode, void *v)
        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 {
@@ -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)) {
-         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;
@@ -158,7 +158,7 @@ static void t_read(int fd, unsigned mode, void *v)
        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:
@@ -166,7 +166,7 @@ static void t_read(int fd, unsigned mode, void *v)
          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;
          }
        }
@@ -253,13 +253,14 @@ whine:
 /* --- @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.
  */
 
-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 };
@@ -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));
+  *ifn = xstrdup(sl->name);
   dstr_destroy(&d);
   return (t);
 
@@ -361,14 +363,18 @@ fail:
   return (0);
 }
 
-/* --- @t_ifname@ --- *
+/* --- @t_setifname@ --- *
  *
  * 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@ --- *
  *
@@ -442,7 +448,7 @@ const tunnel_ops tun_slip = {
   "slip",
   t_init,
   t_create,
-  t_ifname,
+  t_setifname,
   t_inject,
   t_destroy
 };
index c2b6e77..bdf23fe 100644 (file)
@@ -48,29 +48,6 @@ struct tunnel {
   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
@@ -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) {
-    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, {
@@ -117,17 +94,19 @@ static void t_init(void) { return; }
  *
  * 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.
  */
 
-static tunnel *t_create(peer *p)
+static tunnel *t_create(peer *p, char **ifn)
 {
   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);
@@ -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);
+
+  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_ifname(t), p_name(p)); )
+          *ifn, p_name(p)); )
   return (t);
 }
 
@@ -189,7 +174,7 @@ const tunnel_ops tun_unet = {
   "unet",
   t_init,
   t_create,
-  t_ifname,
+  0,
   t_inject,
   t_destroy
 };