rta_free(old_route->rte.attrs);
}
- if (p->net_present != 0)
+ if (NET_AGGR == p->aggr_mode)
{
/* Announce changes */
if (old_bucket)
proto_configure_channel(P, &p->src, cf->src);
proto_configure_channel(P, &p->dst, cf->dst);
+ p->aggr_mode = cf->aggr_mode;
p->aggr_on_count = cf->aggr_on_count;
p->aggr_on_da_count = cf->aggr_on_da_count;
p->aggr_on = cf->aggr_on;
- p->net_present = cf->net_present;
p->merge_by = cf->merge_by;
p->notify_settle_cf = cf->notify_settle_cf;
#define MAX_POTENTIAL_BUCKETS_COUNT 16
+enum aggr_mode {
+ NET_AGGR, PREFIX_AGGR,
+};
+
struct aggregator_config {
struct proto_config c;
struct channel_config *src, *dst;
+ enum aggr_mode aggr_mode;
uint aggr_on_count;
uint aggr_on_da_count;
struct aggr_item *aggr_on;
- int net_present;
const struct f_line *merge_by;
struct settle_config notify_settle_cf;
};
struct aggregator_proto {
struct proto p;
struct channel *src, *dst;
-
+ enum aggr_mode aggr_mode;
/* Buckets by aggregator rule */
HASH(struct aggregator_bucket) buckets;
uint aggr_on_count;
uint aggr_on_da_count;
struct aggr_item *aggr_on;
- int net_present;
/* Merge filter */
const struct f_line *merge_by;
this_proto = proto_config_new(&proto_aggregator, $1);
this_channel = AGGREGATOR_CFG->src = channel_config_new(NULL, "source", 0, this_proto);
AGGREGATOR_CFG->dst = channel_config_new(NULL, "destination", 0, this_proto);
- AGGREGATOR_CFG->src->ra_mode = AGGREGATOR_CFG->dst->ra_mode = RA_ANY;
+
+ /*
+ * Aggregation mode is set to prefix aggregation by default, in which case we want to receive
+ * updates with the best routes.
+ */
+ AGGREGATOR_CFG->aggr_mode = PREFIX_AGGR;
+ AGGREGATOR_CFG->src->ra_mode = RA_OPTIMAL;
+ AGGREGATOR_CFG->dst->ra_mode = RA_ANY;
AGGREGATOR_CFG->notify_settle_cf = (struct settle_config) {
.min = 10 MS_,
if (AGGREGATOR_CFG->aggr_on)
cf_error("Only one aggregate on clause allowed");
- AGGREGATOR_CFG->net_present = 0;
int count = 0;
for (const struct aggr_item_node *item = $3; item; item = item->next) {
log(L_WARN "type %d sacode %d", item->i.type, item->i.sa.sa_code);
- if (item->i.type == AGGR_ITEM_STATIC_ATTR && item->i.sa.sa_code == SA_NET)
- AGGREGATOR_CFG->net_present = 1;
+ /*
+ * If NET attribute is present, aggregate routes within the same net
+ * and receive updates with any routes.
+ */
+ if (item->i.type == AGGR_ITEM_STATIC_ATTR && item->i.sa.sa_code == SA_NET) {
+ AGGREGATOR_CFG->aggr_mode = NET_AGGR;
+ AGGREGATOR_CFG->src->ra_mode = RA_ANY;
+ }
count++;
}
if (AGGREGATOR_CFG->src->table->addr_type != AGGREGATOR_CFG->dst->table->addr_type)
cf_error("Both rtables in aggregator must have the same network type");
- if (AGGREGATOR_CFG->net_present == 0)
+ if (PREFIX_AGGR == AGGREGATOR_CFG->aggr_mode)
if (AGGREGATOR_CFG->src->table->addr_type != NET_IP4 && AGGREGATOR_CFG->src->table->addr_type != NET_IP6)
cf_error("Trie aggregation is available only for IP4 or IPv6 networks");
};