diff options
author | Don Slice <dslice@cumulusnetworks.com> | 2016-11-11 00:49:45 +0100 |
---|---|---|
committer | Don Slice <dslice@cumulusnetworks.com> | 2016-11-14 16:06:46 +0100 |
commit | 9274cde5dc2dc92045ca3bb5dbd4162d81beb549 (patch) | |
tree | caa9ed6a2556b424ed8995d79711cdecd9cf8938 /zebra | |
parent | watchquagga: Signal when we are actually up and running (diff) | |
download | frr-9274cde5dc2dc92045ca3bb5dbd4162d81beb549.tar.xz frr-9274cde5dc2dc92045ca3bb5dbd4162d81beb549.zip |
zebra: remove recursively derived static routes correctly
Problem reported that in certain configs, when a router is initially
booted and the link is bounced, we can end up with a bogus static route
in the table. This was due to the assumption in zebra_rnh that a static
route would not be recursively resolved through another static route with
a different next-hop. This fix changes this assumption. Tested manually
and bgp-min, ospf-min, and vrf-min run with no new failures.
Ticket: CM-13328
Signed-off-by: Don Slice
Reviewed-by: CCR-5338
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/zebra_rnh.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 216a9d1ce..be1411091 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -542,31 +542,28 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, RNODE_FOREACH_RIB(static_rn, srib) { if (srib->type == ZEBRA_ROUTE_STATIC) - break; /* currently works for only 1 static route. */ - } + continue; - if (!srib) // unexpected - continue; + /* Set the filter flag for the correct nexthop - static route may + * be having multiple. We care here only about registered nexthops. + */ + for (nexthop = srib->nexthop; nexthop; nexthop = nexthop->next) + { + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->gate.ipv4.s_addr == nrn->p.u.prefix4.s_addr) + { + if (num_resolving_nh) + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); + else + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: - /* Set the filter flag for the correct nexthop - static route may - * be having multiple. We care here only about registered nexthops. - */ - for (nexthop = srib->nexthop; nexthop; nexthop = nexthop->next) - { - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->gate.ipv4.s_addr == nrn->p.u.prefix4.s_addr) - { - if (num_resolving_nh) - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); - else - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: if (memcmp(&nexthop->gate.ipv6,&nrn->p.u.prefix6, 16) == 0) { if (num_resolving_nh) @@ -580,20 +577,22 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, } } - if (IS_ZEBRA_DEBUG_NHT) - { - prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN); - if (prn && rib) - zlog_debug("%u:%s: NH change %s, scheduling static route %s", - vrfid, bufn, num_resolving_nh ? - "" : "(filtered by route-map)", bufs); - else - zlog_debug("%u:%s: NH unreachable, scheduling static route %s", - vrfid, bufn, bufs); + if (IS_ZEBRA_DEBUG_NHT) + { + prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN); + if (prn && rib) + zlog_debug("%u:%s: NH change %s, scheduling static route %s", + vrfid, bufn, num_resolving_nh ? + "" : "(filtered by route-map)", bufs); + else + zlog_debug("%u:%s: NH unreachable, scheduling static route %s", + vrfid, bufn, bufs); + } + + SET_FLAG(srib->flags, ZEBRA_FLAG_CHANGED); + SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED); } - SET_FLAG(srib->flags, ZEBRA_FLAG_CHANGED); - SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED); rib_queue_add(static_rn); } } |