diff options
author | Martin Mares <mj@ucw.cz> | 2000-03-01 00:19:52 +0100 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2000-03-01 00:19:52 +0100 |
commit | 6a636392d33627944df9d5a9573932cdc0bf6da5 (patch) | |
tree | 9e689378151af5a882085356ba7d3bb3ebabcbbb /sysdep/linux | |
parent | e69e4ed9349ee28262fe74f70e7e52c181d5d098 (diff) | |
download | bird-6a636392d33627944df9d5a9573932cdc0bf6da5.tar bird-6a636392d33627944df9d5a9573932cdc0bf6da5.zip |
Rewrote interface type detection logic. The `unnumbered' flag is now per
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.
Diffstat (limited to 'sysdep/linux')
-rw-r--r-- | sysdep/linux/netlink/netlink.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 54e5cd8..fd8689d 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -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 |