Skip to content

Commit

Permalink
controller: Update MAC binding timestamp
Browse files Browse the repository at this point in the history
To achieve that add thread that will handle
statistics requests and delegate the processing
to defined functions. This allows the thread to
be flexible enough, so it could be extended in future
if needed.

At the same time connected the thread with the MAC
cache I-P node to have the timestamp updates. The
updates should happen once per dump_period
(3/4 of the aging threshold) per chassis only if
the MAC binding is actively used.

Reported-at: https://bugzilla.redhat.com/2189924
Signed-off-by: Ales Musil <amusil@redhat.com>
Signed-off-by: Mark Michelson <mmichels@redhat.com>
  • Loading branch information
almusil authored and putnopvut committed Aug 24, 2023
1 parent b57f60a commit e1ab41e
Show file tree
Hide file tree
Showing 7 changed files with 596 additions and 7 deletions.
4 changes: 3 additions & 1 deletion controller/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ controller_ovn_controller_SOURCES = \
controller/mirror.h \
controller/mirror.c \
controller/mac_cache.h \
controller/mac_cache.c
controller/mac_cache.c \
controller/statctrl.h \
controller/statctrl.c

controller_ovn_controller_LDADD = lib/libovn.la $(OVS_LIBDIR)/libopenvswitch.la
man_MANS += controller/ovn-controller.8
Expand Down
93 changes: 93 additions & 0 deletions controller/mac_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ mac_cache_threshold_get_value_ms(const struct sbrec_datapath_binding *dp,
static void
mac_cache_threshold_remove(struct hmap *thresholds,
struct mac_cache_threshold *threshold);
static void
mac_cache_update_req_delay(struct hmap *thresholds, uint64_t *req_delay);

bool
mac_cache_threshold_add(struct mac_cache_data *data,
Expand Down Expand Up @@ -167,6 +169,84 @@ mac_cache_mac_bindings_clear(struct mac_cache_data *data)
}
}

struct mac_cache_stats {
struct ovs_list list_node;

int64_t idle_age_ms;

union {
/* Common data to identify MAC binding. */
struct mac_cache_mb_data mb;
} data;
};

void
mac_cache_mb_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.mb = (struct mac_cache_mb_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
};

if (ofp_stats->match.flow.dl_type == htons(ETH_TYPE_IP)) {
stats->data.mb.ip = in6_addr_mapped_ipv4(ofp_stats->match.flow.nw_src);
} else {
stats->data.mb.ip = ofp_stats->match.flow.ipv6_src;
}

ovs_list_push_back(stats_list, &stats->list_node);
}

void
mac_cache_mb_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_MAC_BINDING];
long long timewall_now = time_wall_msec();

struct mac_cache_stats *stats;
LIST_FOR_EACH_POP (stats, list_node, stats_list) {
struct mac_cache_mac_binding *mc_mb =
mac_cache_mac_binding_find(cache_data, &stats->data.mb);
if (!mc_mb) {
free(stats);
continue;
}

struct uuid *dp_uuid = &mc_mb->sbrec_mb->datapath->header_.uuid;
struct mac_cache_threshold *threshold =
mac_cache_threshold_find(thresholds, 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_mb->sbrec_mb->timestamp) >=
threshold->dump_period) {
sbrec_mac_binding_set_timestamp(mc_mb->sbrec_mb, timewall_now);
}

free(stats);
}

mac_cache_update_req_delay(thresholds, req_delay);
}

void
mac_cache_stats_destroy(struct ovs_list *stats_list)
{
struct mac_cache_stats *stats;
LIST_FOR_EACH_POP (stats, list_node, stats_list) {
free(stats);
}
}

static uint32_t
mac_cache_mb_data_hash(const struct mac_cache_mb_data *mb_data)
{
Expand Down Expand Up @@ -268,3 +348,16 @@ mac_cache_threshold_remove(struct hmap *thresholds,
hmap_remove(thresholds, &threshold->hmap_node);
free(threshold);
}

static void
mac_cache_update_req_delay(struct hmap *thresholds, uint64_t *req_delay)
{
struct mac_cache_threshold *threshold;

uint64_t dump_period = UINT64_MAX;
HMAP_FOR_EACH (threshold, hmap_node, thresholds) {
dump_period = MIN(dump_period, threshold->dump_period);
}

*req_delay = dump_period < UINT64_MAX ? dump_period : 0;
}
7 changes: 7 additions & 0 deletions controller/mac_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,11 @@ void mac_cache_mac_binding_remove(struct mac_cache_data *data,
void mac_cache_mac_bindings_clear(struct mac_cache_data *data);
bool mac_cache_sb_mac_binding_updated(const struct sbrec_mac_binding *mb);

void
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_stats_destroy(struct ovs_list *stats_list);

#endif /* controller/mac_cache.h */
13 changes: 12 additions & 1 deletion controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#include "hmapx.h"
#include "mirror.h"
#include "mac_cache.h"
#include "statctrl.h"

VLOG_DEFINE_THIS_MODULE(main);

Expand Down Expand Up @@ -4903,6 +4904,7 @@ main(int argc, char *argv[])
lflow_init();
mirror_init();
vif_plug_provider_initialize();
statctrl_init();

/* Connect to OVS OVSDB instance. */
struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
Expand Down Expand Up @@ -5248,7 +5250,7 @@ main(int argc, char *argv[])
runtime_data_ovs_interface_shadow_handler);

engine_add_input(&en_mac_cache, &en_runtime_data,
engine_noop_handler);
mac_cache_runtime_data_handler);
engine_add_input(&en_mac_cache, &en_sb_mac_binding,
mac_cache_sb_mac_binding_handler);
engine_add_input(&en_mac_cache, &en_sb_datapath_binding,
Expand Down Expand Up @@ -5310,6 +5312,8 @@ main(int argc, char *argv[])
engine_get_internal_data(&en_template_vars);
struct ed_type_lb_data *lb_data =
engine_get_internal_data(&en_lb_data);
struct mac_cache_data *mac_cache_data =
engine_get_internal_data(&en_mac_cache);

ofctrl_init(&lflow_output_data->group_table,
&lflow_output_data->meter_table,
Expand Down Expand Up @@ -5698,6 +5702,11 @@ main(int argc, char *argv[])
}
}

if (mac_cache_data) {
statctrl_update(br_int->name);
statctrl_run(ovnsb_idl_txn, mac_cache_data);
}

ofctrl_seqno_update_create(
ofctrl_seq_type_nb_cfg,
get_nb_cfg(sbrec_sb_global_table_get(
Expand Down Expand Up @@ -5807,6 +5816,7 @@ main(int argc, char *argv[])
if (br_int) {
ofctrl_wait();
pinctrl_wait(ovnsb_idl_txn);
statctrl_wait(ovnsb_idl_txn);
}

binding_wait();
Expand Down Expand Up @@ -5941,6 +5951,7 @@ main(int argc, char *argv[])
patch_destroy();
mirror_destroy();
encaps_destroy();
statctrl_destroy();
if_status_mgr_destroy(if_mgr);
shash_destroy(&vif_plug_deleted_iface_ids);
shash_destroy(&vif_plug_changed_iface_ids);
Expand Down

0 comments on commit e1ab41e

Please sign in to comment.