From 85a291ff3055f0b10ffc199138c67305f5b3fc98 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 2 May 2000 15:21:51 +0000 Subject: IPv6 address classification fixes. --- lib/ipv6.c | 22 +++++++++++++++++----- nest/iface.c | 2 ++ nest/rt-table.c | 16 ++++++++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/ipv6.c b/lib/ipv6.c index fa84b84..a8b114d 100644 --- a/lib/ipv6.c +++ b/lib/ipv6.c @@ -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; } diff --git a/nest/iface.c b/nest/iface.c index b58b183..d41b39d 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -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)); diff --git a/nest/rt-table.c b/nest/rt-table.c index ae27ceb..0c4c9e7 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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) -- cgit v1.2.3