]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
IPv6 address classification fixes.
authorMartin Mares <mj@ucw.cz>
Tue, 2 May 2000 15:21:51 +0000 (15:21 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 2 May 2000 15:21:51 +0000 (15:21 +0000)
lib/ipv6.c
nest/iface.c
nest/rt-table.c

index fa84b84dbbc99ed695dafc9b4aca31f02731fa24..a8b114d6789810b15ca59239bfb0b6a97f62c25c 100644 (file)
@@ -67,12 +67,11 @@ ipv6_classify(ip_addr *a)
 {
   u32 x = a->addr[0];
 
-  /* FIXME: Relax these requirements? */
   if ((x & 0xe0000000) == 0x20000000)          /* Aggregatable Global Unicast Address */
     return IADDR_HOST | SCOPE_UNIVERSE;
-  if ((x & 0xfc000000) == 0xe8000000)          /* Link-Local Address */
+  if ((x & 0xffc00000) == 0xfe800000)          /* Link-Local Address */
     return IADDR_HOST | SCOPE_LINK;
-  if ((x & 0xfc000000) == 0xec000000)          /* Site-Local Address */
+  if ((x & 0xffc00000) == 0xfec00000)          /* Site-Local Address */
     return IADDR_HOST | SCOPE_SITE;
   if ((x & 0xff000000) == 0xff000000)          /* Multicast Address */
     {
@@ -86,8 +85,21 @@ ipv6_classify(ip_addr *a)
        case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
        }
     }
-  if (!x && !a->addr[1] && !a->addr[2] && a->addr[3] == 1)
-    return IADDR_HOST | SCOPE_HOST;            /* Loopback address */
+  if (!x && !a->addr[1] && !a->addr[2])
+    {
+      u32 y = a->addr[3];
+      if (y == 1)
+       return IADDR_HOST | SCOPE_HOST;         /* Loopback address */
+      /* IPv4 compatible addresses */
+      if (y >= 0x7f000000 && y < 0x80000000)
+       return IADDR_HOST | SCOPE_HOST;
+      if ((y & 0xff000000) == 0x0a000000 ||
+         (y & 0xffff0000) == 0xc0a80000 ||
+         (y & 0xfff00000) == 0xac100000)
+       return IADDR_HOST | SCOPE_SITE;
+      if (y >= 0x01000000 && y < 0xe0000000)
+       return IADDR_HOST | SCOPE_UNIVERSE;
+    }
   return IADDR_INVALID;
 }
 
index b58b183dee79f7e358c454f7bc06d2a12e2f05ac..d41b39daea17ca4448af547c96aacb9cce019e03 100644 (file)
@@ -371,8 +371,10 @@ ifa_update(struct ifa *a)
 
   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);
+#ifndef IPV6
   if ((i->flags & IF_BROADCAST) && !ipa_nonzero(a->brd))
     log(L_ERR "Missing broadcast address for interface %s", i->name);
+#endif
 
   b = mb_alloc(if_pool, sizeof(struct ifa));
   memcpy(b, a, sizeof(struct ifa));
index ae27ceb739e4860275b49b0263b7b741837725fe..0c4c9e733313b072d0866a4030a5b8afd45e6d38 100644 (file)
@@ -232,10 +232,18 @@ rte_validate(rte *e)
       c = ipa_classify(n->n.prefix);
       if (c < 0 || !(c & IADDR_HOST))
        {
-         if (!ipa_nonzero(n->n.prefix) && n->n.pxlen <= 1)
-           return 1;           /* Default route and half-default route is OK */
-         log(L_WARN "Ignoring bogus route %I/%d received from %I via %s",
-             n->n.prefix, n->n.pxlen, e->attrs->from, e->attrs->proto->name);
+         if (!ipa_nonzero(n->n.prefix))
+           {
+             /* Various default routes */
+#ifdef IPV6
+             if (n->n.pxlen == 96)
+#else
+             if (n->n.pxlen <= 1)
+#endif
+               return 1;
+           }
+         log(L_WARN "Ignoring bogus route %I/%d received via %s",
+             n->n.prefix, n->n.pxlen, e->attrs->proto->name);
          return 0;
        }
       if ((c & IADDR_SCOPE_MASK) < e->attrs->proto->min_scope)