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

Reply via email to