diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-09-01 16:28:19 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-09-06 00:56:36 +0200 |
commit | 915902cb82cfd57fa059b3a508ea9973bd056a96 (patch) | |
tree | b5080590b20f95b85fd9e491d30c7fc05a8ca1ec /zebra/zebra_rib.c | |
parent | Merge pull request #1108 from donaldsharp/rip (diff) | |
download | frr-915902cb82cfd57fa059b3a508ea9973bd056a96.tar.xz frr-915902cb82cfd57fa059b3a508ea9973bd056a96.zip |
zebra: Allow zebra to delete self originated routes
With the change to make zebra pass routes to the kernel
with the 'correct' proto name, it caused zebra to
not properly recognize them on startup again
the next time such that the route would not
be deleted.
Modify rt_netlink.c to notice that we have a
self originated route and to properly mark
the type of route it was.
Modify rib_table_sweep to mark the nexthops
as active so that when we go to delete the
self originated routes it would properly
delete from the kernel.
Fixes: #1061
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to '')
-rw-r--r-- | zebra/zebra_rib.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index deb434bd3..d74f84a1f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2072,8 +2072,9 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, for (ALL_NEXTHOPS(re->nexthop, nexthop)) { inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN); - zlog_debug("%s: %s %s with flags %s%s%s", func, + zlog_debug("%s: %s %s[%u] with flags %s%s%s", func, (nexthop->rparent ? " NH" : "NH"), straddr, + nexthop->ifindex, (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""), @@ -2644,23 +2645,50 @@ static void rib_sweep_table(struct route_table *table) struct route_node *rn; struct route_entry *re; struct route_entry *next; + struct nexthop *nexthop; int ret = 0; - if (table) - for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) - RNODE_FOREACH_RE_SAFE(rn, re, next) - { - if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) - continue; + if (!table) + return; - if (re->type == ZEBRA_ROUTE_KERNEL - && CHECK_FLAG(re->flags, - ZEBRA_FLAG_SELFROUTE)) { - ret = rib_uninstall_kernel(rn, re); - if (!ret) - rib_delnode(rn, re); - } - } + for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { + RNODE_FOREACH_RE_SAFE(rn, re, next) + { + if (IS_ZEBRA_DEBUG_RIB) + route_entry_dump(&rn->p, NULL, re); + + if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) + continue; + + if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE)) + continue; + + /* + * So we are starting up and have received + * routes from the kernel that we have installed + * from a previous run of zebra but not cleaned + * up ( say a kill -9 ) + * But since we haven't actually installed + * them yet( we received them from the kernel ) + * we don't think they are active. + * So let's pretend they are active to actually + * remove them. + * In all honesty I'm not sure if we should + * mark them as active when we receive them + * This is startup only so probably ok. + * + * If we ever decide to move rib_sweep_table + * to a different spot (ie startup ) + * this decision needs to be revisited + */ + for (ALL_NEXTHOPS(re->nexthop, nexthop)) + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + + ret = rib_uninstall_kernel(rn, re); + if (!ret) + rib_delnode(rn, re); + } + } } /* Sweep all RIB tables. */ @@ -2669,8 +2697,10 @@ void rib_sweep_route(void) struct vrf *vrf; struct zebra_vrf *zvrf; - RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) - if ((zvrf = vrf->info) != NULL) { + RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { + if ((zvrf = vrf->info) == NULL) + continue; + rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]); rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]); } |