rte_free_quick(old_exported);
}
-static void
+USE_RESULT static _Bool
rt_notify_basic(struct channel *c, struct rte_export_internal *e)
{
if (e->pub.new)
e->pub.old = NULL;
if (!e->pub.new && !e->pub.old)
- return;
+ return 0;
- do_rt_notify(c, e);
+ return 1;
}
-static void
+USE_RESULT static _Bool
rt_notify_accepted(struct channel *c, struct rte_export_internal *e)
{
// struct proto *p = c->proto;
if (new_first && (e->pub.new = export_filter(c, e->pub.new, &e->rt_free, 0)))
new_best = e->pub.new;
else
- return;
+ return 0;
}
if (!new_best && !old_best)
- return;
+ return 0;
e->pub.new = new_best;
e->pub.new_src = new_best ? new_best->attrs->src : NULL;
e->pub.old = old_best;
e->pub.old_src = old_best ? old_best->attrs->src : NULL;
- do_rt_notify(c, e);
+ return 1;
}
}
-static void
+USE_RESULT static _Bool
rt_notify_merged(struct channel *c, struct rte_export_internal *e)
{
/* We assume that all rte arguments are either NULL or rte_is_valid() */
/* This check should be done by the caller */
if (!e->new_best && !e->old_best)
- return;
+ return 0;
/* Check whether the change is relevant to the merged route */
if ((e->new_best == e->old_best) &&
(e->pub.new != e->pub.old) &&
!rte_mergable(e->new_best, e->pub.new) &&
!rte_mergable(e->old_best, e->pub.old))
- return;
+ return 0;
if (e->new_best)
c->stats.exp_updates_received++;
e->pub.old = NULL;
if (!e->pub.new && !e->pub.old)
- return;
+ return 0;
e->pub.new_src = e->pub.new ? e->pub.new->attrs->src : NULL;
e->pub.old_src = e->pub.old ? e->pub.old->attrs->src : NULL;
- do_rt_notify(c, e);
+ return 1;
}
e.pub.new_src = new_best ? new_best->attrs->src : NULL;
e.pub.old = old_best;
e.pub.old_src = old_best ? old_best->attrs->src : NULL;
- rt_notify_basic(c, &e);
+ if (!rt_notify_basic(c, &e))
+ goto next_channel;
}
break;
case RA_ANY:
if (new != old)
- rt_notify_basic(c, &e);
+ if (!rt_notify_basic(c, &e))
+ goto next_channel;
break;
case RA_ACCEPTED:
- rt_notify_accepted(c, &e);
+ if (!rt_notify_accepted(c, &e))
+ goto next_channel;
break;
case RA_MERGED:
- rt_notify_merged(c, &e);
+ if (!rt_notify_merged(c, &e))
+ goto next_channel;
break;
}
+ do_rt_notify(c, &e);
+
+next_channel:
/* Discard temporary rte */
if (e.rt_free)
rte_free(e.rt_free);
ee.pub.new_src = e->attrs->src;
ee.pub.old = e;
ee.pub.old_src = e->attrs->src;
- rt_notify_basic(c, &ee);
+ if (!rt_notify_basic(c, &ee))
+ goto next_rte;
break;
case RA_ACCEPTED:
- rt_notify_accepted(c, &ee);
+ if (!rt_notify_accepted(c, &ee))
+ goto next_rte;
break;
case RA_MERGED:
- rt_notify_merged(c, &ee);
+ if (!rt_notify_merged(c, &ee))
+ goto next_rte;
break;
default:
ASSERT(0);
}
+ do_rt_notify(c, &ee);
+
/* Discard temporary rte */
+next_rte:
if (ee.rt_free)
rte_free(ee.rt_free);
}