Add FDB timestamp update to mac_cache and use the statctrl thread to dump the needed stats. The updates should happen once per dump_period (3/4 of the aging threshold) per chassis only if the FDB is actively used.
Signed-off-by: Ales Musil <[email protected]> --- controller/mac_cache.c | 50 ++++++++++++++++++++++++++++++++++++++++++ controller/mac_cache.h | 7 ++++++ controller/statctrl.c | 13 ++++++++++- tests/ovn.at | 19 +++++++++++++--- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/controller/mac_cache.c b/controller/mac_cache.c index a8fc272a1..7e4feeed7 100644 --- a/controller/mac_cache.c +++ b/controller/mac_cache.c @@ -315,6 +315,56 @@ mac_cache_mb_stats_run(struct ovs_list *stats_list, uint64_t *req_delay, mac_cache_update_req_delay(thresholds, req_delay); } +void +mac_cache_fdb_stats_process_flow_stats(struct ovs_list *stats_list, + struct ofputil_flow_stats *ofp_stats) +{ + struct mac_cache_stats *stats = xmalloc(sizeof *stats); + + stats->idle_age_ms = ofp_stats->idle_age * 1000; + stats->data.fdb = (struct mac_cache_fdb_data) { + .port_key = ofp_stats->match.flow.regs[MFF_LOG_INPORT - MFF_REG0], + .dp_key = ntohll(ofp_stats->match.flow.metadata), + .mac = ofp_stats->match.flow.dl_src + }; + + ovs_list_push_back(stats_list, &stats->list_node); +} + +void +mac_cache_fdb_stats_run(struct ovs_list *stats_list, uint64_t *req_delay, + void *data) +{ + struct mac_cache_data *cache_data = data; + struct hmap *thresholds = &cache_data->thresholds[MAC_CACHE_FDB]; + long long timewall_now = time_wall_msec(); + + struct mac_cache_stats *stats; + LIST_FOR_EACH_POP (stats, list_node, stats_list) { + struct mac_cache_fdb *mc_fdb = mac_cache_fdb_find(cache_data, + &stats->data.fdb); + if (!mc_fdb) { + free(stats); + continue; + } + + struct mac_cache_threshold *threshold = + mac_cache_threshold_find(thresholds, &mc_fdb->dp_uuid); + /* If "idle_age" is under threshold it means that the mac binding is + * used on this chassis. Also make sure that we don't update the + * timestamp more than once during the dump period. */ + if (stats->idle_age_ms < threshold->value && + (timewall_now - mc_fdb->sbrec_fdb->timestamp) >= + threshold->dump_period) { + sbrec_fdb_set_timestamp(mc_fdb->sbrec_fdb, timewall_now); + } + + free(stats); + } + + mac_cache_update_req_delay(thresholds, req_delay); +} + void mac_cache_stats_destroy(struct ovs_list *stats_list) { diff --git a/controller/mac_cache.h b/controller/mac_cache.h index 7bde84564..ea8aa7c1b 100644 --- a/controller/mac_cache.h +++ b/controller/mac_cache.h @@ -112,6 +112,13 @@ mac_cache_mb_stats_process_flow_stats(struct ovs_list *stats_list, struct ofputil_flow_stats *ofp_stats); void mac_cache_mb_stats_run(struct ovs_list *stats_list, uint64_t *req_delay, void *data); + +void +mac_cache_fdb_stats_process_flow_stats(struct ovs_list *stats_list, + struct ofputil_flow_stats *ofp_stats); +void mac_cache_fdb_stats_run(struct ovs_list *stats_list, uint64_t *req_delay, + void *data); + void mac_cache_stats_destroy(struct ovs_list *stats_list); #endif /* controller/mac_cache.h */ diff --git a/controller/statctrl.c b/controller/statctrl.c index 92325fbeb..cb1545cbb 100644 --- a/controller/statctrl.c +++ b/controller/statctrl.c @@ -38,6 +38,7 @@ VLOG_DEFINE_THIS_MODULE(statctrl); enum stat_type { STATS_MAC_BINDING = 0, + STATS_FDB, STATS_MAX, }; @@ -137,6 +138,16 @@ statctrl_init(void) STATS_NODE(MAC_BINDING, mac_binding_request, mac_cache_stats_destroy, mac_cache_mb_stats_process_flow_stats, mac_cache_mb_stats_run); + struct ofputil_flow_stats_request fdb_request = { + .cookie = htonll(0), + .cookie_mask = htonll(0), + .out_port = OFPP_ANY, + .out_group = OFPG_ANY, + .table_id = OFTABLE_LOOKUP_FDB, + }; + STATS_NODE(FDB, fdb_request, mac_cache_stats_destroy, + mac_cache_fdb_stats_process_flow_stats, + mac_cache_fdb_stats_run); statctrl_ctx.thread = ovs_thread_create("ovn_statctrl", statctrl_thread_handler, @@ -151,7 +162,7 @@ statctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, return; } - void *node_data[STATS_MAX] = {mac_cache_data}; + void *node_data[STATS_MAX] = {mac_cache_data, mac_cache_data}; bool schedule_updated = false; long long now = time_msec(); diff --git a/tests/ovn.at b/tests/ovn.at index 04a71bedb..0565113da 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -36457,14 +36457,27 @@ send_packet() { # Send packet to create FDB row send_packet 20 wait_row_count fdb 1 mac='"00:00:00:00:10:20"' +timestamp=$(fetch_column fdb timestamp mac='"00:00:00:00:10:20"') # Set the FDB aging threshold -check ovn-nbctl set logical_switch ls0 other_config:fdb_age_threshold=1 -AT_CHECK([fetch_column nb:logical_switch other_config | grep -q fdb_age_threshold=1]) +check ovn-nbctl set logical_switch ls0 other_config:fdb_age_threshold=5 +AT_CHECK([fetch_column nb:logical_switch other_config | grep -q fdb_age_threshold=5]) check ovn-nbctl --wait=sb sync +# Send few packets for "00:00:00:00:10:20" to indicate that it is still in use +send_packet 20 +sleep 1 +send_packet 20 + # Set the timeout for OVS_WAIT* functions to 5 seconds -OVS_CTL_TIMEOUT=5 +OVS_CTL_TIMEOUT=10 +OVS_WAIT_UNTIL([ + curr_timestamp=$(fetch_column fdb timestamp mac='"00:00:00:00:10:20"') + test "$timestamp" != "$curr_timestamp" +]) +timestamp=$(fetch_column fdb timestamp mac='"00:00:00:00:10:20"') +check $(test "$timestamp" != "") + # Check if the records are removed after some inactivity wait_row_count fdb 0 mac='"00:00:00:00:10:20"' -- 2.41.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
