summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_rib.c
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 /zebra/zebra_rib.c
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
Diffstat (limited to 'zebra/zebra_rib.c')
-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))
{