summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-15 20:59:44 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-15 20:59:44 -0700
commit251018c5741e3518b79da01d24f1fd07aa49e58e (patch)
tree5452f7827a61b020941931318fc5540cab2fa648
parent775e09c69825718c8d24d193e86c826cb0bf8f68 (diff)
downloadquagga-251018c5741e3518b79da01d24f1fd07aa49e58e.tar.bz2
quagga-251018c5741e3518b79da01d24f1fd07aa49e58e.tar.xz
Update RIB/FIB on recursive route state changes
If a link state change event causes a different nexthop, then the RIB (and FIB) need to be updated. Solved by forcing the CHANGED flag. This code could be rearranged to be cleaner in future. Bugfix 3434
-rw-r--r--zebra/zebra_rib.c87
1 files changed, 50 insertions, 37 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 2b120120..92236b6d 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -401,26 +401,33 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
{
/* Directly point connected route. */
newhop = match->nexthop;
- if (newhop)
+ if (!newhop)
+ return 0; /* dead route */
+
+ /* if scanning and the new match is different than the old one
+ * then force the CHANGED flag.
+ * FIXME (have this routine return NULL or nexhop instead)
+ */
+ if (!set && newhop != nexthop)
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+
+ /* recursive route, remember index */
+ if (nexthop->type == NEXTHOP_TYPE_IPV4)
+ nexthop->ifindex = newhop->ifindex;
+
+ switch(newhop->type)
{
- if (nexthop->type == NEXTHOP_TYPE_IPV4)
- nexthop->ifindex = newhop->ifindex;
-
- if (newhop->type == NEXTHOP_TYPE_IFINDEX ||
- newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
- {
- ifp = if_lookup_by_index (newhop->ifindex);
- return (ifp && if_is_operative (ifp));
- }
-
- if (newhop->type == NEXTHOP_TYPE_IFNAME ||
- newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
- {
- ifp = if_lookup_by_name(newhop->ifname);
- return (ifp && if_is_operative (ifp));
- }
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ ifp = if_lookup_by_index (newhop->ifindex);
+ return (ifp && if_is_operative (ifp));
+ case NEXTHOP_TYPE_IFNAME:
+ case NEXTHOP_TYPE_IPV4_IFNAME:
+ ifp = if_lookup_by_name(newhop->ifname);
+ return (ifp && if_is_operative (ifp));
+ default:
+ return 1;
}
- return 1;
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL) ||
match->type == ZEBRA_ROUTE_STATIC)
@@ -527,27 +534,33 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
{
/* Directly point connected route. */
newhop = match->nexthop;
-
- if (newhop)
+ if (!newhop)
+ return 0; /* dead route */
+
+ /* if scanning and the new match is different than the old one
+ * then force the CHANGED flag.
+ * FIXME (have this routine return NULL or nexhop instead)
+ */
+ if (!set && newhop != nexthop)
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+
+ /* recursive route, remember index */
+ if (nexthop->type == NEXTHOP_TYPE_IPV6)
+ nexthop->ifindex = newhop->ifindex;
+
+ switch(newhop->type)
{
- if (nexthop->type == NEXTHOP_TYPE_IPV4)
- nexthop->ifindex = newhop->ifindex;
-
- if (newhop->type == NEXTHOP_TYPE_IFINDEX ||
- newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
- {
- ifp = if_lookup_by_index (newhop->ifindex);
- return (ifp && if_is_operative (ifp));
- }
-
- if (newhop->type == NEXTHOP_TYPE_IFNAME ||
- newhop->type == NEXTHOP_TYPE_IPV4_IFNAME)
- {
- ifp = if_lookup_by_name(newhop->ifname);
- return (ifp && if_is_operative (ifp));
- }
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ ifp = if_lookup_by_index (newhop->ifindex);
+ return (ifp && if_is_operative (ifp));
+ case NEXTHOP_TYPE_IFNAME:
+ case NEXTHOP_TYPE_IPV6_IFNAME:
+ ifp = if_lookup_by_name(newhop->ifname);
+ return (ifp && if_is_operative (ifp));
+ default:
+ return 1;
}
- return 1;
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
{