diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-07-15 20:59:44 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-07-15 20:59:44 -0700 |
commit | 251018c5741e3518b79da01d24f1fd07aa49e58e (patch) | |
tree | 5452f7827a61b020941931318fc5540cab2fa648 | |
parent | 775e09c69825718c8d24d193e86c826cb0bf8f68 (diff) | |
download | quagga-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.c | 87 |
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)) { |