diff --git a/proto/perf/config.Y b/proto/perf/config.Y index 60a96c11..7cab8333 100644 --- a/proto/perf/config.Y +++ b/proto/perf/config.Y @@ -31,6 +31,7 @@ perf_proto_start: proto_start PERF PERF_CFG->repeat = 4; PERF_CFG->threshold_max = 500 MS_; PERF_CFG->threshold_min = 1 MS_; + PERF_CFG->attrs_per_rte = 0; PERF_CFG->keep = 0; PERF_CFG->mode = PERF_MODE_IMPORT; }; @@ -48,6 +49,7 @@ perf_proto_item: | REPEAT NUM { PERF_CFG->repeat = $2; } | THRESHOLD MIN expr_us { PERF_CFG->threshold_min = $3; } | THRESHOLD MAX expr_us { PERF_CFG->threshold_max = $3; } + | ATTRIBUTES NUM { PERF_CFG->attrs_per_rte = $2; } | KEEP bool { PERF_CFG->keep = $2; } | MODE IMPORT { PERF_CFG->mode = PERF_MODE_IMPORT; } | MODE EXPORT { PERF_CFG->mode = PERF_MODE_EXPORT; } diff --git a/proto/perf/perf.c b/proto/perf/perf.c index bfc0f09e..d48ad751 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -90,7 +90,7 @@ struct perf_random_routes { struct rta a; }; -static const uint perf_random_routes_size = sizeof(net_addr) + sizeof(rte *) + RTA_MAX_SIZE; +static const uint perf_random_routes_size = sizeof(struct perf_random_routes) + (RTA_MAX_SIZE - sizeof(struct rta)); static inline s64 timediff(struct timespec *begin, struct timespec *end) { return (end->tv_sec - begin->tv_sec) * (s64) 1000000000 + end->tv_nsec - begin->tv_nsec; } @@ -137,36 +137,40 @@ perf_loop(void *data) ip_addr gw = random_gw(&p->ifa->prefix); - struct timespec ts_begin, ts_generated, ts_rte, ts_update, ts_withdraw; + struct timespec ts_begin, ts_generated, ts_update, ts_withdraw; clock_gettime(CLOCK_MONOTONIC, &ts_begin); + struct rta *a = NULL; + for (uint i=0; idata + offset * i; *((net_addr_ip4 *) &prr->net) = random_net_ip4(); - rta *a = &prr->a; - bzero(a, RTA_MAX_SIZE); + if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) { + a = &prr->a; + bzero(a, RTA_MAX_SIZE); - a->src = p->p.main_source; - a->source = RTS_PERF; - a->scope = SCOPE_UNIVERSE; - a->dest = RTD_UNICAST; + a->src = p->p.main_source; + a->source = RTS_PERF; + a->scope = SCOPE_UNIVERSE; + a->dest = RTD_UNICAST; - a->nh.iface = p->ifa->iface; - a->nh.gw = gw; - a->nh.weight = 1; - } + a->nh.iface = p->ifa->iface; + a->nh.gw = gw; + a->nh.weight = 1; - clock_gettime(CLOCK_MONOTONIC, &ts_generated); + if (p->attrs_per_rte) + a = rta_lookup(a); + } - for (uint i=0; idata + offset * i; - prr->ep = rte_get_temp(&prr->a); + ASSERT(a); + + prr->ep = rte_get_temp(a); prr->ep->pflags = 0; } - clock_gettime(CLOCK_MONOTONIC, &ts_rte); + clock_gettime(CLOCK_MONOTONIC, &ts_generated); for (uint i=0; idata + offset * i; @@ -184,13 +188,12 @@ perf_loop(void *data) clock_gettime(CLOCK_MONOTONIC, &ts_withdraw); s64 gentime = timediff(&ts_begin, &ts_generated); - s64 temptime = timediff(&ts_generated, &ts_rte); - s64 updatetime = timediff(&ts_rte, &ts_update); + s64 updatetime = timediff(&ts_generated, &ts_update); s64 withdrawtime = timediff(&ts_update, &ts_withdraw); if (updatetime NS >= p->threshold_min) - PLOG("exp=%u times: gen=%lu temp=%lu update=%lu withdraw=%lu", - p->exp, gentime, temptime, updatetime, withdrawtime); + PLOG("exp=%u times: gen=%lu update=%lu withdraw=%lu", + p->exp, gentime, updatetime, withdrawtime); if (updatetime NS < p->threshold_max) p->stop = 0; @@ -269,6 +272,7 @@ perf_init(struct proto_config *CF) p->repeat = cf->repeat; p->keep = cf->keep; p->mode = cf->mode; + p->attrs_per_rte = cf->attrs_per_rte; switch (p->mode) { case PERF_MODE_IMPORT: diff --git a/proto/perf/perf.h b/proto/perf/perf.h index 301c6110..8fde01bd 100644 --- a/proto/perf/perf.h +++ b/proto/perf/perf.h @@ -22,6 +22,7 @@ struct perf_config { uint to; uint repeat; uint keep; + uint attrs_per_rte; enum perf_mode mode; }; @@ -39,6 +40,7 @@ struct perf_proto { uint exp; uint stop; uint keep; + uint attrs_per_rte; enum perf_mode mode; };