{
struct nexthop *nexthop;
char buf[PREFIX_STRLEN];
+ rib_dest_t *dest;
+
+ dest = rib_dest_from_rnode(rn);
switch (res) {
case SOUTHBOUND_INSTALL_SUCCESS:
+ dest->selected_fib = re;
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
p, ZAPI_ROUTE_INSTALLED);
break;
case SOUTHBOUND_INSTALL_FAILURE:
+ /*
+ * I am not sure this is the right thing to do here
+ * but the code always set selected_fib before
+ * this assignment was moved here.
+ */
+ dest->selected_fib = re;
+
zsend_route_notify_owner(re->type, re->instance, re->vrf_id,
p, ZAPI_ROUTE_FAIL_INSTALL);
zlog_warn("%u:%s: Route install failed", re->vrf_id,
prefix2str(p, buf, sizeof(buf)));
break;
case SOUTHBOUND_DELETE_SUCCESS:
+ /*
+ * The case where selected_fib is not re is
+ * when we have received a system route
+ * that is overriding our installed route
+ * as such we should leave the selected_fib
+ * pointer alone
+ */
+ if (dest->selected_fib == re)
+ dest->selected_fib = NULL;
for (ALL_NEXTHOPS(re->nexthop, nexthop))
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
break;
case SOUTHBOUND_DELETE_FAILURE:
+ /*
+ * Should we set this to NULL if the
+ * delete fails?
+ */
+ dest->selected_fib = NULL;
zlog_warn("%u:%s: Route Deletion failure", re->vrf_id,
prefix2str(p, buf, sizeof(buf)));
break;
/* If labeled-unicast route, uninstall transit LSP. */
if (zebra_rib_labeled_unicast(re))
zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
-
- dest->selected_fib = NULL;
}
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
return;
}
- dest->selected_fib = new;
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
if (!RIB_SYSTEM_ROUTE(new))
rib_install_kernel(rn, new, NULL);
+ else
+ dest->selected_fib = new;
UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
}
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
-
- dest->selected_fib = NULL;
+ else {
+ /*
+ * We are setting this to NULL here
+ * because that is what we traditionally
+ * have been doing. I am not positive
+ * that this is the right thing to do
+ * but let's leave the code alone
+ * for the RIB_SYSTEM_ROUTE case
+ */
+ dest->selected_fib = NULL;
+ }
/* Update nexthop for route, reset changed flag. */
nexthop_active_update(rn, old, 1);
{
struct nexthop *nexthop = NULL;
int nh_active = 0;
- int installed = 1;
rib_dest_t *dest = rib_dest_from_rnode(rn);
/*
zebra_mpls_lsp_install(zvrf, rn, new);
rib_install_kernel(rn, new, old);
+ } else {
+ /*
+ * We do not need to install the
+ * selected route because it
+ * is already isntalled by
+ * the system( ie not us )
+ * so just mark it as winning
+ * we do need to ensure that
+ * if we uninstall a route
+ * from ourselves we don't
+ * over write this pointer
+ */
+ dest->selected_fib = NULL;
}
-
/* If install succeeded or system route, cleanup flags
* for prior route. */
- if (installed && new != old) {
+ if (new != old) {
if (RIB_SYSTEM_ROUTE(new)) {
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
NEXTHOP_FLAG_FIB);
}
}
-
- /* Update for redistribution. */
- if (installed)
- dest->selected_fib = new;
}
/*
* failed, we
* may need to uninstall and delete for redistribution.
*/
- if (!nh_active || !installed) {
+ if (!nh_active) {
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
- dest->selected_fib = NULL;
+ else
+ dest->selected_fib = NULL;
}
} else {
/*
* to add routes.
*/
if (!RIB_SYSTEM_ROUTE(new)) {
- int in_fib = 0;
+ bool in_fib = false;
for (ALL_NEXTHOPS(new->nexthop, nexthop))
if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB)) {
- in_fib = 1;
+ in_fib = true;
break;
}
if (!in_fib)
UNSET_FLAG(rtnh->flags,
NEXTHOP_FLAG_FIB);
+ /*
+ * This is a non FRR route
+ * as such we should mark
+ * it as deleted
+ */
dest->selected_fib = NULL;
} else {
/* This means someone else, other than Zebra,