#include "lib/hash.h"
#include "lib/resource.h"
#include "lib/timer.h"
+#include "lib/settle.h"
/* Configuration structure */
struct config {
#include "nest/iface.h"
#include "filter/filter.h"
#include "proto/aggregator/aggregator.h"
+#include "lib/settle.h"
#include <stdlib.h>
#include <assert.h>
+
/*
#include "nest/route.h"
#include "nest/iface.h"
run_aggregation(p);
}
+static void
+aggregate_on_settle_timer(struct settle *timer)
+{
+ struct aggregator_proto *p = SKIP_BACK(struct aggregator_proto, p, timer);
+ run_aggregation(p);
+}
+
/*
* Set static attribute in @rta from static attribute in @old according to @sa.
*/
HASH_REMOVE2(p->buckets, AGGR_BUCK, p->p.pool, old_bucket);
sl_free(old_bucket);
}
+
+ settle_kick(&p->aggr_timer);
}
static int
p->aggr_on = cf->aggr_on;
p->net_present = cf->net_present;
p->merge_by = cf->merge_by;
+ p->aggr_timer_cf = cf->aggr_timer_cf;
P->rt_notify = aggregator_rt_notify;
P->preexport = aggregator_preexport;
/* Assign default route to the root */
p->root->bucket = new_bucket;
+ settle_init(&p->aggr_timer, &p->aggr_timer_cf, aggregate_on_settle_timer, p);
+
return PS_UP;
}
}
HASH_WALK_END;
+ settle_cancel(&p->aggr_timer);
+
delete_trie(p->root);
p->root = NULL;
TRACE(D_EVENTS, "Reconfiguring");
+ /* Compare timer configuration */
+ if (cf->aggr_timer_cf.min != p->aggr_timer_cf.min || cf->aggr_timer_cf.max != p->aggr_timer_cf.max)
+ return 0;
+
/* Compare numeric values (shortcut) */
if (cf->aggr_on_count != p->aggr_on_count)
return 0;
#include "nest/bird.h"
#include "nest/protocol.h"
#include "lib/hash.h"
+#include "lib/settle.h"
#define MAX_POTENTIAL_BUCKETS_COUNT 16
struct aggr_item *aggr_on;
int net_present;
const struct f_line *merge_by;
+ struct settle_config aggr_timer_cf;
};
struct aggregator_route {
uint addr_type;
slab *trie_slab;
struct trie_node *root;
+ struct settle_config aggr_timer_cf;
+ struct settle aggr_timer;
int before_count;
int after_count;
};
CF_HDR
#include "proto/aggregator/aggregator.h"
+#include "lib/settle.h"
CF_DEFINES
CF_DECLS
-CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY)
+CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY, RELOAD, AFTER)
%type <ai> aggr_item aggr_list
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;
+
+ AGGREGATOR_CFG->aggr_timer_cf = (struct settle_config) {
+ .min = 10 MS_,
+ .max = 100 MS_,
+ };
};
aggregator_proto_item:
$4->args++;
AGGREGATOR_CFG->merge_by = $4;
}
+ | RELOAD AFTER settle { AGGREGATOR_CFG->aggr_timer_cf = $3; }
;
aggregator_proto_opts: /* empty */ | aggregator_proto_opts aggregator_proto_item ';' ;
}
;
+/* Settle timer configuration */
+settle:
+ expr_us expr_us {
+ if ($1 > $2)
+ cf_error("Minimum settle time %t is bigger than maximum settle time %t", $1, $2);
+ $$.min = $1 MS_;
+ $$.max = $2 MS_;
+ }
+ ;
+
CF_CODE
CF_END