zebra: fix ifindex test condition (BZ#487)
When the same ip address is used on several interfaces,
and one of them gets deleted (or equivalent: set to down and
then address removed), rib_delete_ipv[46] will also remove
the connected route from other interfaces.
rib_delete_ipv[46] is called twice when an interface is
deleted:
- for the "ifdown" event
- for the address removal
(note: this may be specific to the netlink interface of linux)
The second call does not find the connected route to that same
ifindex anymore, but deletes similar connected routes to any
other ifindex instead.
Reason: the ifindex check is on the same level as the check
for ZEBRA_ROUTE_CONNECT/NEXTHOP_TYPE_IFINDEX. If everything
matches except for the ifindex, the "else" part (intended for
different route types) is executed, thus removing the route
from the wrong interface.
fix: move ifindex check inside the "then" part of the check
for ZEBRA_ROUTE_CONNECT/NEXTHOP_TYPE_IFINDEX. Now connected
routes to other ifindexes will not spill over to the "else"
part for different route types anymore.
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 7263389..d239501 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1883,8 +1883,10 @@
if (rib->type != type)
continue;
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
- nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
+ nexthop->type == NEXTHOP_TYPE_IFINDEX)
{
+ if (nexthop->ifindex != ifindex)
+ continue;
if (rib->refcnt)
{
rib->refcnt--;
@@ -2431,8 +2433,10 @@
if (rib->type != type)
continue;
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
- nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
+ nexthop->type == NEXTHOP_TYPE_IFINDEX)
{
+ if (nexthop->ifindex != ifindex)
+ continue;
if (rib->refcnt)
{
rib->refcnt--;