@@ -32,6 +32,8 @@ northd_ovn_northd_SOURCES = \
northd/en-lr-stateful.h \
northd/en-ls-stateful.c \
northd/en-ls-stateful.h \
+ northd/en-sampling-app.c \
+ northd/en-sampling-app.h \
northd/inc-proc-northd.c \
northd/inc-proc-northd.h \
northd/ipam.c \
@@ -25,6 +25,7 @@
#include "en-ls-stateful.h"
#include "en-northd.h"
#include "en-meters.h"
+#include "en-sampling-app.h"
#include "lflow-mgr.h"
#include "lib/inc-proc-eng.h"
@@ -86,6 +87,10 @@ lflow_get_input_data(struct engine_node *node,
lflow_input->ovn_internal_version_changed =
global_config->ovn_internal_version_changed;
lflow_input->svc_monitor_mac = global_config->svc_monitor_mac;
+
+ struct ed_type_sampling_app_data *sampling_app_data =
+ engine_get_input_data("sampling_app", node);
+ lflow_input->sampling_apps = &sampling_app_data->apps;
}
void en_lflow_run(struct engine_node *node, void *data)
new file mode 100644
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2024, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "openvswitch/vlog.h"
+
+#include "en-sampling-app.h"
+
+VLOG_DEFINE_THIS_MODULE(en_sampling_app);
+
+/* Static function declarations. */
+static void sampling_app_table_add(struct sampling_app_table *,
+ const struct nbrec_sampling_app *);
+static uint8_t sampling_app_table_get_id(const struct sampling_app_table *,
+ enum sampling_app);
+static void sampling_app_table_reset(struct sampling_app_table *);
+static enum sampling_app sampling_app_get_by_type(const char *app_type);
+
+void *
+en_sampling_app_init(struct engine_node *node OVS_UNUSED,
+ struct engine_arg *arg OVS_UNUSED)
+{
+ struct ed_type_sampling_app_data *data = xzalloc(sizeof *data);
+ sampling_app_table_reset(&data->apps);
+ return data;
+}
+
+void
+en_sampling_app_cleanup(void *data OVS_UNUSED)
+{
+}
+
+void
+en_sampling_app_run(struct engine_node *node, void *data_)
+{
+ const struct nbrec_sampling_app_table *nb_sampling_app_table =
+ EN_OVSDB_GET(engine_get_input("NB_sampling_app", node));
+ struct ed_type_sampling_app_data *data = data_;
+
+ sampling_app_table_reset(&data->apps);
+
+ const struct nbrec_sampling_app *sa;
+ NBREC_SAMPLING_APP_TABLE_FOR_EACH (sa, nb_sampling_app_table) {
+ sampling_app_table_add(&data->apps, sa);
+ }
+
+ engine_set_node_state(node, EN_UPDATED);
+}
+
+uint8_t
+sampling_app_get_id(const struct sampling_app_table *app_table,
+ enum sampling_app app)
+{
+ return sampling_app_table_get_id(app_table, app);
+}
+
+/* Static functions. */
+static void
+sampling_app_table_add(struct sampling_app_table *table,
+ const struct nbrec_sampling_app *sa)
+{
+ enum sampling_app app = sampling_app_get_by_type(sa->type);
+
+ if (app == SAMPLING_APP_MAX) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "Unexpected Sampling_App type: %s", sa->type);
+ return;
+ }
+ table->app_ids[app] = sa->id;
+}
+
+static uint8_t
+sampling_app_table_get_id(const struct sampling_app_table *table,
+ enum sampling_app app)
+{
+ ovs_assert(app < SAMPLING_APP_MAX);
+ return table->app_ids[app];
+}
+
+static void
+sampling_app_table_reset(struct sampling_app_table *table)
+{
+ for (size_t i = 0; i < SAMPLING_APP_MAX; i++) {
+ table->app_ids[i] = SAMPLING_APP_ID_NONE;
+ }
+}
+
+static const char *app_types[] = {
+ [SAMPLING_APP_DROP_DEBUG] = "drop",
+ [SAMPLING_APP_ACL_NEW] = "acl-new",
+ [SAMPLING_APP_ACL_EST] = "acl-est",
+};
+
+static enum sampling_app
+sampling_app_get_by_type(const char *app_type)
+{
+ for (size_t app = 0; app < ARRAY_SIZE(app_types); app++) {
+ if (!strcmp(app_type, app_types[app])) {
+ return app;
+ }
+ }
+ return SAMPLING_APP_MAX;
+}
new file mode 100644
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef EN_SAMPLING_APP_H
+#define EN_SAMPLING_APP_H 1
+
+/* OVS includes. */
+#include "openvswitch/shash.h"
+
+/* OVN includes. */
+#include "lib/inc-proc-eng.h"
+#include "lib/ovn-nb-idl.h"
+
+/* Valid sample IDs are in the 1..255 interval. */
+#define SAMPLING_APP_ID_NONE 0
+
+/* Supported sampling applications. */
+enum sampling_app {
+ SAMPLING_APP_DROP_DEBUG,
+ SAMPLING_APP_ACL_NEW,
+ SAMPLING_APP_ACL_EST,
+ SAMPLING_APP_MAX,
+};
+
+struct sampling_app_table {
+ uint8_t app_ids[SAMPLING_APP_MAX];
+};
+
+struct ed_type_sampling_app_data {
+ struct sampling_app_table apps;
+};
+
+void *en_sampling_app_init(struct engine_node *, struct engine_arg *);
+void en_sampling_app_cleanup(void *data);
+void en_sampling_app_run(struct engine_node *, void *data);
+uint8_t sampling_app_get_id(const struct sampling_app_table *,
+ enum sampling_app);
+
+#endif /* EN_SAMPLING_APP_H */
@@ -39,6 +39,7 @@
#include "en-lflow.h"
#include "en-northd-output.h"
#include "en-meters.h"
+#include "en-sampling-app.h"
#include "en-sync-sb.h"
#include "en-sync-from-sb.h"
#include "unixctl.h"
@@ -61,7 +62,8 @@ static unixctl_cb_func chassis_features_list;
NB_NODE(meter, "meter") \
NB_NODE(bfd, "bfd") \
NB_NODE(static_mac_binding, "static_mac_binding") \
- NB_NODE(chassis_template_var, "chassis_template_var")
+ NB_NODE(chassis_template_var, "chassis_template_var") \
+ NB_NODE(sampling_app, "sampling_app")
enum nb_engine_node {
#define NB_NODE(NAME, NAME_STR) NB_##NAME,
@@ -138,6 +140,7 @@ enum sb_engine_node {
* avoid sparse errors. */
static ENGINE_NODE_WITH_CLEAR_TRACK_DATA(northd, "northd");
static ENGINE_NODE(sync_from_sb, "sync_from_sb");
+static ENGINE_NODE(sampling_app, "sampling_app");
static ENGINE_NODE(lflow, "lflow");
static ENGINE_NODE(mac_binding_aging, "mac_binding_aging");
static ENGINE_NODE(mac_binding_aging_waker, "mac_binding_aging_waker");
@@ -170,6 +173,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_lb_data, &en_nb_logical_router,
lb_data_logical_router_handler);
+ engine_add_input(&en_sampling_app, &en_nb_sampling_app, NULL);
+
engine_add_input(&en_global_config, &en_nb_nb_global,
global_config_nb_global_handler);
engine_add_input(&en_global_config, &en_sb_sb_global,
@@ -251,6 +256,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_lflow, &en_sb_logical_dp_group, NULL);
engine_add_input(&en_lflow, &en_global_config,
node_global_config_handler);
+
+ engine_add_input(&en_lflow, &en_sampling_app, NULL);
+
engine_add_input(&en_lflow, &en_northd, lflow_northd_handler);
engine_add_input(&en_lflow, &en_port_group, lflow_port_group_handler);
engine_add_input(&en_lflow, &en_lr_stateful, lflow_lr_stateful_handler);
@@ -190,6 +190,7 @@ struct lflow_input {
const struct hmap *svc_monitor_map;
bool ovn_internal_version_changed;
const char *svc_monitor_mac;
+ const struct sampling_app_table *sampling_apps;
};
extern int parallelization_state;
@@ -1,7 +1,7 @@
{
"name": "OVN_Northbound",
- "version": "7.4.0",
- "cksum": "1908497390 35615",
+ "version": "7.5.0",
+ "cksum": "1137408189 36223",
"tables": {
"NB_Global": {
"columns": {
@@ -691,6 +691,20 @@
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
"indexes": [["chassis"]],
- "isRoot": true}
+ "isRoot": true},
+ "Sampling_App": {
+ "columns": {
+ "type": {"type": {"key": {"type": "string",
+ "enum": ["set", ["drop", "acl-new", "acl-est"]]}}},
+ "id": {"type": {"key": {"type": "integer",
+ "minInteger": 1,
+ "maxInteger": 255}}},
+ "external_ids": {
+ "type": {"key": "string", "value": "string",
+ "min": 0, "max": "unlimited"}}
+ },
+ "indexes": [["type"]],
+ "isRoot": true
+ }
}
}
@@ -5093,4 +5093,20 @@ or
</column>
</group>
</table>
+ <table name="Sampling_App">
+ <column name="type">
+ The type of the application to be configured for sampling. Currently
+ supported options are: "drop", "acl-new", "acl-est".
+ </column>
+ <column name="id">
+ The identifier to be encoded in the samples generated for this type of
+ application. This identifier is used as part of the sample's
+ observation domain ID.
+ </column>
+ <group title="Common Columns">
+ <column name="external_ids">
+ See <em>External IDs</em> at the beginning of this document.
+ </column>
+ </group>
+ </table>
</database>
@@ -12479,6 +12479,23 @@ check_engine_stats lflow recompute nocompute
AT_CLEANUP
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([Sampling_App incremental processing])
+
+ovn_start
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+
+ovn-nbctl create Sampling_App type="acl-new" id="42"
+check_row_count nb:Sampling_App 1
+check_engine_stats sampling_app recompute nocompute
+check_engine_stats northd norecompute nocompute
+check_engine_stats lflow recompute nocompute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+AT_CLEANUP
+])
+
OVN_FOR_EACH_NORTHD_NO_HV([
AT_SETUP([NAT with match])
ovn_start