]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Rewrote interface type detection logic. The `unnumbered' flag is now per
authorMartin Mares <mj@ucw.cz>
Tue, 29 Feb 2000 23:19:52 +0000 (23:19 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 29 Feb 2000 23:19:52 +0000 (23:19 +0000)
address, not per interface (hence it's ifa->flags & IA_UNNUMBERED) and
should be set reliably. IF_MULTIACCESS should be fixed now, but it isn't
wise to rely on it on interfaces configured with /30 prefix.

TODO
nest/iface.c
nest/iface.h
nest/rt-dev.c
sysdep/linux/netlink/netlink.c
sysdep/unix/krt-iface.c

diff --git a/TODO b/TODO
index f0c54866c52f3b6f48b1cd1277ac28003514d1d0..4b033b089328a6a178ce5955b629316313ccf5be 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,7 +3,6 @@ Core
 - IPv6: hashing functions etc.
 
 - krt-iface: check whether the interface alias hack works
-- krt-iface and netlink: unnumberedness of tunnels
 
 - better memory allocators
 - real attribute cache
index ce233cd80a030d61c87c300423ef66c7d3953500..9b4eff00d9df9ed5b34b2c8a7c6fba65d027addc 100644 (file)
@@ -36,16 +36,25 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
 
   if (!(i->flags & IF_UP))
     return 0;
-  if ((i->flags & IF_UNNUMBERED) && ipa_equal(*a, i->addr->opposite))
-    return 1;
   WALK_LIST(b, i->addrs)
-    if (ipa_in_net(*a, b->prefix, b->pxlen))
-      {
-       if (ipa_equal(*a, b->prefix) || /* Network address */
-           ipa_equal(*a, b->brd) ||    /* Broadcast */
-           ipa_equal(*a, b->ip))       /* Our own address */
-         return -1;
-       return 1;
+    {
+      if (ipa_equal(*a, b->ip))
+       return -1;
+      if (b->flags & IA_UNNUMBERED)
+       {
+         if (ipa_equal(*a, b->opposite))
+           return 1;
+       }
+      else
+       {
+         if (ipa_in_net(*a, b->prefix, b->pxlen))
+           {
+             if (ipa_equal(*a, b->prefix) ||   /* Network address */
+                 ipa_equal(*a, b->brd))        /* Broadcast */
+               return -1;
+             return 1;
+           }
+       }
       }
   return 0;
 }
@@ -184,9 +193,10 @@ list iface_list;
 void
 ifa_dump(struct ifa *a)
 {
-  debug("\t%I, net %I/%-2d bc %I -> %I%s%s\n", a->ip, a->prefix, a->pxlen, a->brd, a->opposite,
+  debug("\t%I, net %I/%-2d bc %I -> %I%s%s%s\n", a->ip, a->prefix, a->pxlen, a->brd, a->opposite,
        (a->flags & IF_UP) ? "" : " DOWN",
-       (a->flags & IA_PRIMARY) ? "" : " SEC");
+       (a->flags & IA_PRIMARY) ? "" : " SEC",
+       (a->flags & IA_UNNUMBERED) ? " UNNUM" : "");
 }
 
 void
@@ -205,8 +215,6 @@ if_dump(struct iface *i)
     debug(" LINK-UP");
   if (i->flags & IF_MULTIACCESS)
     debug(" MA");
-  if (i->flags & IF_UNNUMBERED)
-    debug(" UNNUM");
   if (i->flags & IF_BROADCAST)
     debug(" BC");
   if (i->flags & IF_MULTICAST)
@@ -492,7 +500,8 @@ ifa_update(struct ifa *a)
            b->pxlen == a->pxlen &&
            ipa_equal(b->brd, a->brd) &&
            ipa_equal(b->opposite, a->opposite) &&
-           b->scope == a->scope)
+           b->scope == a->scope &&
+           !((b->flags ^ a->flags) & IA_UNNUMBERED))
          {
            b->flags |= IF_UPDATED;
            return b;
@@ -500,6 +509,12 @@ ifa_update(struct ifa *a)
        ifa_delete(b);
        break;
       }
+
+  if (!(i->flags & IF_MULTIACCESS) && a->pxlen < BITS_PER_IP_ADDRESS - 2)
+    log(L_WARN "Strange prefix length %d for point-to-point interface %s", a->pxlen, i->name);
+  if ((i->flags & IF_BROADCAST) && !ipa_nonzero(a->brd))
+    log(L_ERR "Missing broadcast address for interface %s", i->name);
+
   b = mb_alloc(if_pool, sizeof(struct ifa));
   memcpy(b, a, sizeof(struct ifa));
   add_tail(&i->addrs, &b->n);
@@ -545,8 +560,9 @@ auto_router_id(void)
   j = NULL;
   WALK_LIST(i, iface_list)
     if ((i->flags & IF_LINK_UP) &&
-       !(i->flags & (IF_UNNUMBERED | IF_IGNORE | IF_ADMIN_DOWN)) &&
+       !(i->flags & (IF_IGNORE | IF_ADMIN_DOWN)) &&
        i->addr &&
+       !(i->addr->flags & IA_UNNUMBERED) &&
        (!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip)))
       j = i;
   if (!j)
@@ -633,11 +649,12 @@ if_show_addr(struct ifa *a)
     bsprintf(opp, ", opposite %I", a->opposite);
   else
     opp[0] = 0;
-  cli_msg(-1003, "\t%I/%d (%s%s%s, scope %s)",
+  cli_msg(-1003, "\t%I/%d (%s%s%s, scope %s%s)",
          a->ip, a->pxlen,
          (a->flags & IA_PRIMARY) ? "Primary" : (a->flags & IA_SECONDARY) ? "Secondary" : "???",
          broad, opp,
-         ip_scope_text(a->scope));
+         ip_scope_text(a->scope),
+         (a->flags & IA_UNNUMBERED) ? ", unnumbered" : "");
 }
 
 void
@@ -650,9 +667,7 @@ if_show(void)
   WALK_LIST(i, iface_list)
     {
       cli_msg(-1001, "%s %s (index=%d)", i->name, (i->flags & IF_UP) ? "up" : "DOWN", i->index);
-      if (i->flags & IF_UNNUMBERED)
-       type = "UnNum-PtP";
-      else if (!(i->flags & IF_MULTIACCESS))
+      if (!(i->flags & IF_MULTIACCESS))
        type = "PtP";
       else
        type = "MultiAccess";
index b13ec719dc57094adf2074cc1a40e2c436af9d46..5ac9f2f79c63557e867fb516ac362da458017cb8 100644 (file)
@@ -40,16 +40,16 @@ struct iface {
 
 #define IF_UP 1                                /* IF_LINK_UP and IP address known */
 #define IF_MULTIACCESS 2
-#define IF_UNNUMBERED 4
-#define IF_BROADCAST 8
-#define IF_MULTICAST 0x10
-#define IF_ADMIN_DOWN 0x40
-#define IF_LOOPBACK 0x80
-#define IF_IGNORE 0x100                        /* Not to be used by routing protocols (loopbacks etc.) */
-#define IF_LINK_UP 0x200
+#define IF_BROADCAST 4
+#define IF_MULTICAST 8
+#define IF_ADMIN_DOWN 0x10
+#define IF_LOOPBACK 0x20
+#define IF_IGNORE 0x40                 /* Not to be used by routing protocols (loopbacks etc.) */
+#define IF_LINK_UP 0x80
 
 #define IA_PRIMARY 0x10000             /* This address is primary */
 #define IA_SECONDARY 0x20000           /* This address has been reported as secondary by the kernel */
+#define IA_UNNUMBERED 0x40000          /* This address belongs to an unnumbered device */
 #define IA_FLAGS 0xff0000
 
 #define IF_JUST_CREATED 0x10000000     /* Send creation event as soon as possible */
index b9253ccbfa1a99005ebdf0e48c856a4075778cf9..edadeba5c9ce04ecbce2cb8b3a2433aa8312842f 100644 (file)
@@ -56,10 +56,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
       A.iface = ad->iface;
       A.eattrs = NULL;
       a = rta_lookup(&A);
-      if (ad->flags & IF_UNNUMBERED)
-       n = net_get(p->table, ad->opposite, ad->pxlen);
-      else
-       n = net_get(p->table, ad->prefix, ad->pxlen);
+      n = net_get(p->table, ad->prefix, ad->pxlen);
       e = rte_get_temp(a);
       e->net = n;
       e->pflags = 0;
index 54e5cd8bbb0c801b1aaf262f9f0b7d56aff0acf6..fd8689dcd9383129dcd176326c3f8435b657c45c 100644 (file)
@@ -301,13 +301,14 @@ nl_parse_link(struct nlmsghdr *h, int scan)
       fl = i->ifi_flags;
       if (fl & IFF_UP)
        f.flags |= IF_LINK_UP;
-      /* FIXME: Unnumberedness of tunnels */
-      if (fl & IFF_POINTOPOINT)
-       f.flags |= IF_UNNUMBERED | IF_MULTICAST;
-      if (fl & IFF_LOOPBACK)
-       f.flags |= IF_LOOPBACK | IF_IGNORE;
-      if (fl & IFF_BROADCAST)
-       f.flags |= IF_BROADCAST | IF_MULTICAST;
+      if (fl & IFF_LOOPBACK)           /* Loopback */
+       f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
+      else if (fl & IFF_POINTOPOINT)   /* PtP */
+       f.flags |= IF_MULTICAST;
+      else if (fl & IFF_BROADCAST)     /* Broadcast */
+       f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST;
+      else
+       f.flags |= IF_MULTIACCESS;      /* NBMA */
       if_update(&f);
     }
 }
@@ -350,15 +351,6 @@ nl_parse_addr(struct nlmsghdr *h)
       return;
     }
 
-#ifndef IPV6
-  if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
-      (ifi->flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
-    {
-      log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
-      new = 0;
-    }
-#endif
-
   bzero(&ifa, sizeof(ifa));
   ifa.iface = ifi;
   if (i->ifa_flags & IFA_F_SECONDARY)
@@ -367,26 +359,37 @@ nl_parse_addr(struct nlmsghdr *h)
   memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL] ? : a[IFA_ADDRESS]), sizeof(ifa.ip));
   ipa_ntoh(ifa.ip);
   ifa.pxlen = i->ifa_prefixlen;
-  if (ifi->flags & IF_UNNUMBERED)
+  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS ||
+      i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
     {
+      log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
+      new = 0;
+    }
+  if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
+    {
+      ifa.flags |= IA_UNNUMBERED;
       memcpy(&ifa.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(ifa.opposite));
       ipa_ntoh(ifa.opposite);
-      ifa.brd = ifa.opposite;
+      ifa.prefix = ifa.brd = ifa.opposite;
     }
-#ifndef IPV6
-  else if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
+  else
     {
-      memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
-      ipa_ntoh(ifa.brd);
-    }
+      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2)
+       ifa.opposite = ipa_opposite(ifa.ip);
+#ifndef IPV6
+      if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
+       {
+         memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
+         ipa_ntoh(ifa.brd);
+       }
 #endif
-  /* else a NBMA link */
-  ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
+      ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
+    }
 
-  DBG("KIF: IF%d(%s): %s IPA %I, net %I/%d, brd %I, opp %I\n",
+  DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %I/%d, brd %I, opp %I\n",
       ifi->index, ifi->name,
       new ? "added" : "removed",
-      ifa.ip, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
+      ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
   if (new)
     ifa_update(&ifa);
   else
index 8c82ffdf6ec81a0ec17355138f395823861e08fe..2b774a13abc5a229c33ca0acba9bfa79859b6573 100644 (file)
@@ -94,12 +94,15 @@ scan_ifs(struct ifreq *r, int cnt)
 
       if (fl & IFF_POINTOPOINT)
        {
-         i.flags |= IF_UNNUMBERED;
-         a.pxlen = BITS_PER_IP_ADDRESS;
+         a.flags |= IA_UNNUMBERED;
          if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0)
            { err = "SIOCGIFDSTADDR"; goto faulty; }
          get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL);
+         a.prefix = a.opposite;
+         a.pxlen = BITS_PER_IP_ADDRESS;
        }
+      else
+       a.prefix = ipa_and(a.ip, ipa_mkmask(a.pxlen));
       if (fl & IFF_LOOPBACK)
        i.flags |= IF_LOOPBACK | IF_IGNORE;
       if (1
@@ -107,12 +110,11 @@ scan_ifs(struct ifreq *r, int cnt)
          && (fl & IFF_MULTICAST)
 #endif
 #ifndef CONFIG_UNNUM_MULTICAST
-         && !(i.flags & IF_UNNUMBERED)
+         && !(a.flags & IA_UNNUMBERED)
 #endif
         )
        i.flags |= IF_MULTICAST;
 
-      a.prefix = ipa_and(a.ip, ipa_mkmask(a.pxlen));
       if (a.pxlen < 32)
        {
          a.brd = ipa_or(a.prefix, ipa_not(ipa_mkmask(a.pxlen)));