Hey in netlink.c, there is this piece of code: #v+ if (a[RTA_GATEWAY]) { neighbor *ng; ra->dest = RTD_ROUTER; memcpy(&ra->gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra->gw)); ipa_ntoh(ra->gw); #ifdef IPV6 /* Silently skip strange 6to4 routes */ if (ipa_in_net(ra->gw, IPA_NONE, 96)) return; #endif ng = neigh_find2(&p->p, &ra->gw, ra->iface, (i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); if (!ng || (ng->scope == SCOPE_HOST)) { log(L_ERR "KRT: Received route %I/%d with strange next-hop %I", net->n.prefix, net->n.pxlen, ra->gw); return; } } #v- In turns, it calls neigh_find2() which delegates the decision to if_connected(). if_connected() will return an error if it thinks that the gateway is not part of the prefix of one of the configured IP addresses. This means that if I have the following setup: ip route add 203.0.113.4/32 dev vnet2 ip route add 203.0.113.15/32 via 203.0.113.4 dev vnet2 BIRD will complain about "strange next-hop" while the setup is perfectly valid. I don't need an IP address on an interface to route traffic on it. I would think the check should just be removed. If the kernel says this is a valid gateway, it likely is. However, I can't find the reason the check was added. In the past, this was just a warning: #v+ + ng = neigh_find(&p->p, &ra.gw, 0); + if (ng) + ra.iface = ng->iface; + else + /* FIXME: Remove this warning? */ + log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", ra.gw, net->n.prefix, net->n.pxlen); #v- (commit aa64578641c15b137172acc927d9d7af5914576b) But this was made an error in commit 9d4d38d1a5d67f5485d2b2fa439c879583dfdcb0. #v+ - ng = neigh_find(&p->p, &ra.gw, 0); + ng = neigh_find2(&p->p, &ra.gw, ifa, 0); if (ng && ng->scope) + { + if (ng->iface != ifa) + log(L_WARN "KRT: Route with unexpected iface for %I/%d", net->n.prefix, net->n.pxlen); ra.iface = ng->iface; + } else - /* FIXME: Remove this warning? Handle it somehow... */ + { log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", ra.gw, net->n.prefix, net->n.pxlen); + return; + } #v- Commit message says "Fixes some problems related to link-local routes in KRT interface". Does this ring any bell? -- Avoid temporary variables. - The Elements of Programming Style (Kernighan & Plauger)
On Wed, Jun 21, 2017 at 05:11:55PM +0200, Vincent Bernat wrote:
Hey
in netlink.c, there is this piece of code: ... In turns, it calls neigh_find2() which delegates the decision to if_connected(). if_connected() will return an error if it thinks that the gateway is not part of the prefix of one of the configured IP addresses.
This means that if I have the following setup:
ip route add 203.0.113.4/32 dev vnet2 ip route add 203.0.113.15/32 via 203.0.113.4 dev vnet2
BIRD will complain about "strange next-hop" while the setup is perfectly valid. I don't need an IP address on an interface to route traffic on it.
Hi It is expected behavior. Next hops are validated against interface prefixes reported by OS, not against device routes in routing table. See e.g. https://www.mail-archive.com/bird-users@network.cz/msg01896.html Which discusses the same issue just in context of Static protocol instead of Kernel protocol. Note that when learning route from the kernel you could workaround it by using 'onlink' route flag.
I would think the check should just be removed. If the kernel says this is a valid gateway, it likely is.
Well, that would work in an ideal world, but in practice kernel can give you inconsistent or invalid results. E.g., if you have these two routes and remove the first, the second stays in kernel alone. But if you start from empty table and try to add just the second one, it is rejected.
However, I can't find the reason the check was added.
Each protocol (including Kernel protocol) is expected to send only routes with valid next-hops. BIRD does recursive resolution of next-hops only for recursive routes. For regular routes next-hops are validated against interface prefixes. So the check was added to be consistent with these assumptions.
In the past, this was just a warning:
Commit message says "Fixes some problems related to link-local routes in KRT interface". Does this ring any bell?
The patch primarily added interface as a part of neighbor resolution, the change from a warning to an error was a secondary change, probably just to be consistent with other protocols. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
participants (2)
-
Ondrej Zajicek -
Vincent Bernat