summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDon Slice <dslice@cumulusnetworks.com>2016-11-11 00:49:45 +0100
committerDon Slice <dslice@cumulusnetworks.com>2016-11-14 16:06:46 +0100
commit9274cde5dc2dc92045ca3bb5dbd4162d81beb549 (patch)
treecaa9ed6a2556b424ed8995d79711cdecd9cf8938 /zebra
parentwatchquagga: Signal when we are actually up and running (diff)
downloadfrr-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.c69
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);
}
}