Add new I-P node that will store all the data for intreconnect
learned service monitors. In the future, support for synchronization
of service monitors between ovn deployments will be added,
this node will help us correctly process service monitors that were
learned from the interconnect southbound database.

This node is needed in many ways to create logical flows for service monitors
(arp/nd replays), when ovn-ic creates a flow we need to trigger logical flow
creations for the learned records.

As design choice there is only single lflow_ref for all ic_learned
related logical_flows that makes them not being thread safe and only
main thread can generate them during full recompute of lflow node.

Signed-off-by: Alexandra Rukomoinikova <arukomoinikova@k2.cloud>
---
minor corrections in the code (in northd, controller: Add support for remote LB 
health checks patch),
in the previous version there was an error in the tests during rebase and the 
test did not pass, I fixed it
---
 northd/en-northd.c       | 47 +++++++++++++++++++++++++++++++++---
 northd/en-northd.h       |  6 ++++-
 northd/inc-proc-northd.c | 12 ++++++++++
 northd/northd.c          | 52 ++++++++++++++++++++++++++++++++++++++++
 northd/northd.h          | 18 +++++++++++++-
 ovn-sb.ovsschema         |  5 ++--
 ovn-sb.xml               |  5 ++++
 7 files changed, 138 insertions(+), 7 deletions(-)

diff --git a/northd/en-northd.c b/northd/en-northd.c
index 7be01c777..cd62bf3dd 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -41,6 +41,10 @@ static void
 northd_get_input_data(struct engine_node *node,
                       struct northd_input *input_data)
 {
+    input_data->nbrec_mirror_by_type_and_sink =
+        engine_ovsdb_node_get_index(
+            engine_get_input("NB_mirror", node),
+            "nbrec_mirror_by_type_and_sink");
     input_data->sbrec_chassis_by_name =
         engine_ovsdb_node_get_index(
             engine_get_input("SB_chassis", node),
@@ -61,10 +65,10 @@ northd_get_input_data(struct engine_node *node,
         engine_ovsdb_node_get_index(
             engine_get_input("SB_fdb", node),
             "sbrec_fdb_by_dp_and_port");
-    input_data->nbrec_mirror_by_type_and_sink =
+    input_data->sbrec_service_monitor_by_learned_type =
         engine_ovsdb_node_get_index(
-            engine_get_input("NB_mirror", node),
-            "nbrec_mirror_by_type_and_sink");
+            engine_get_input("SB_service_monitor", node),
+            "sbrec_service_monitor_by_learned_type");
 
     input_data->nbrec_logical_switch_table =
         EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
@@ -119,6 +123,11 @@ northd_get_input_data(struct engine_node *node,
     input_data->svc_monitor_mac_ea = global_config->svc_monitor_mac_ea;
     input_data->features = &global_config->features;
     input_data->vxlan_mode = global_config->vxlan_mode;
+
+    /* Add Service Monitor data for interconnect learned records. */
+    struct ic_learned_svcs_data *ic_learned_svcs_data =
+        engine_get_input_data("ic_learned_svcs", node);
+    input_data->ic_learned_svs = &ic_learned_svcs_data->ic_learned_svs;
 }
 
 enum engine_node_state
@@ -437,6 +446,23 @@ en_bfd_sync_run(struct engine_node *node, void *data)
     return new_state;
 }
 
+enum engine_node_state
+en_ic_learned_svcs_run(struct engine_node *node, void *data_)
+{
+    struct ic_learned_svcs_data *data = data_;
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_service_monitor", node),
+            "sbrec_service_monitor_by_learned_type");
+
+    ic_learned_svcs_cleanup(data);
+    ic_learned_svcs_init(data);
+    build_ic_learned_svcs_map(&data->ic_learned_svs,
+        sbrec_service_monitor_by_learned_type);
+
+    return EN_UPDATED;
+}
+
 void
 *en_northd_init(struct engine_node *node OVS_UNUSED,
                 struct engine_arg *arg OVS_UNUSED)
@@ -487,6 +513,15 @@ void
     return data;
 }
 
+void
+*en_ic_learned_svcs_init(struct engine_node *node OVS_UNUSED,
+                         struct engine_arg *arg OVS_UNUSED)
+{
+    struct ic_learned_svcs_data *data = xzalloc(sizeof *data);
+    ic_learned_svcs_init(data);
+    return data;
+}
+
 void
 en_northd_cleanup(void *data)
 {
@@ -559,3 +594,9 @@ en_bfd_sync_cleanup(void *data)
 {
     bfd_sync_destroy(data);
 }
+
+void
+en_ic_learned_svcs_cleanup(void *data)
+{
+    ic_learned_svcs_cleanup(data);
+}
diff --git a/northd/en-northd.h b/northd/en-northd.h
index 4f744a6c5..6c1e2ed23 100644
--- a/northd/en-northd.h
+++ b/northd/en-northd.h
@@ -54,5 +54,9 @@ bfd_sync_northd_change_handler(struct engine_node *node,
                                void *data OVS_UNUSED);
 enum engine_node_state en_bfd_sync_run(struct engine_node *node, void *data);
 void en_bfd_sync_cleanup(void *data OVS_UNUSED);
-
+void *en_ic_learned_svcs_init(struct engine_node *node OVS_UNUSED,
+                              struct engine_arg *arg OVS_UNUSED);
+void en_ic_learned_svcs_cleanup(void *data);
+enum engine_node_state
+en_ic_learned_svcs_run(struct engine_node *node, void *data_);
 #endif /* EN_NORTHD_H */
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index d43bfc16c..f5e9c8a81 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -179,6 +179,7 @@ static ENGINE_NODE(advertised_route_sync);
 static ENGINE_NODE(learned_route_sync, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(dynamic_routes);
 static ENGINE_NODE(group_ecmp_route, CLEAR_TRACKED_DATA);
+static ENGINE_NODE(ic_learned_svcs);
 
 void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
                           struct ovsdb_idl_loop *sb)
@@ -209,6 +210,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_acl_id, &en_nb_acl, NULL);
     engine_add_input(&en_acl_id, &en_sb_acl_id, NULL);
 
+    engine_add_input(&en_ic_learned_svcs, &en_sb_service_monitor, NULL);
+
     engine_add_input(&en_northd, &en_nb_mirror, NULL);
     engine_add_input(&en_northd, &en_nb_mirror_rule, NULL);
     engine_add_input(&en_northd, &en_nb_static_mac_binding, NULL);
@@ -224,6 +227,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_northd, &en_sb_service_monitor, NULL);
     engine_add_input(&en_northd, &en_sb_static_mac_binding, NULL);
     engine_add_input(&en_northd, &en_sb_chassis_template_var, NULL);
+    engine_add_input(&en_northd, &en_ic_learned_svcs, NULL);
     engine_add_input(&en_northd, &en_sb_fdb, northd_sb_fdb_change_handler);
     engine_add_input(&en_northd, &en_global_config,
                      northd_global_config_handler);
@@ -354,6 +358,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_lflow, &en_multicast_igmp,
                      lflow_multicast_igmp_handler);
     engine_add_input(&en_lflow, &en_sb_acl_id, NULL);
+    engine_add_input(&en_lflow, &en_ic_learned_svcs, NULL);
 
     engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL);
     engine_add_input(&en_sync_to_sb_addr_set, &en_lr_stateful, NULL);
@@ -507,6 +512,13 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
                                 "sbrec_ecmp_nexthop_by_ip_and_port",
                                 sbrec_ecmp_nexthop_by_ip_and_port);
 
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type
+        = ovsdb_idl_index_create1(sb->idl,
+                                  &sbrec_service_monitor_col_ic_learned);
+    engine_ovsdb_node_add_index(&en_sb_service_monitor,
+                                "sbrec_service_monitor_by_learned_type",
+                                sbrec_service_monitor_by_learned_type);
+
     struct ed_type_global_config *global_config =
         engine_get_internal_data(&en_global_config);
     unixctl_command_register("debug/chassis-features-list", "", 0, 0,
diff --git a/northd/northd.c b/northd/northd.c
index 764575f21..3c29a4da9 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -11070,6 +11070,34 @@ build_bfd_map(const struct nbrec_bfd_table 
*nbrec_bfd_table,
     }
 }
 
+
+void
+build_ic_learned_svcs_map(
+    struct hmap *ic_learned_svcs_map,
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type)
+{
+    struct sbrec_service_monitor *key;
+
+    key = sbrec_service_monitor_index_init_row(
+        sbrec_service_monitor_by_learned_type);
+
+    sbrec_service_monitor_set_ic_learned(key, true);
+
+    const struct sbrec_service_monitor *sbrec_mon;
+    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sbrec_mon, key,
+        sbrec_service_monitor_by_learned_type) {
+        uint32_t hash = sbrec_mon->port;
+        hash = hash_string(sbrec_mon->ip, hash);
+        hash = hash_string(sbrec_mon->logical_port, hash);
+        struct service_monitor_info *mon_info = xzalloc(sizeof *mon_info);
+        mon_info->sbrec_mon = sbrec_mon;
+        mon_info->required = true;
+        hmap_insert(ic_learned_svcs_map, &mon_info->hmap_node, hash);
+    }
+
+    sbrec_service_monitor_index_destroy_row(key);
+}
+
 /* Returns a string of the IP address of the router port 'op' that
  * overlaps with 'ip_s".  If one is not found, returns NULL.
  *
@@ -19433,6 +19461,13 @@ bfd_sync_destroy(struct bfd_sync_data *data)
     sset_destroy(&data->bfd_ports);
 }
 
+void
+ic_learned_svcs_init(struct ic_learned_svcs_data *data)
+{
+    hmap_init(&data->ic_learned_svs);
+    data->lflow_ref = lflow_ref_create();
+}
+
 void
 northd_destroy(struct northd_data *data)
 {
@@ -19488,6 +19523,23 @@ bfd_destroy(struct bfd_data *data)
     __bfd_destroy(&data->bfd_connections);
 }
 
+static void
+__ic_learned_svcs_cleanup(struct hmap *ic_learned_svs_map)
+{
+    struct service_monitor_info *mon_info;
+    HMAP_FOR_EACH_POP (mon_info, hmap_node, ic_learned_svs_map) {
+        free(mon_info);
+    }
+    hmap_destroy(ic_learned_svs_map);
+}
+
+void
+ic_learned_svcs_cleanup(struct ic_learned_svcs_data *data)
+{
+    __ic_learned_svcs_cleanup(&data->ic_learned_svs);
+    lflow_ref_destroy(data->lflow_ref);
+}
+
 void
 route_policies_destroy(struct route_policies_data *data)
 {
diff --git a/northd/northd.h b/northd/northd.h
index ac00c4ec4..5d4a596f2 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -71,13 +71,17 @@ struct northd_input {
     /* ACL ID inputs. */
     const struct acl_id_data *acl_id_data;
 
+    /* Service Monitor data for interconnect learned records.*/
+    struct hmap *ic_learned_svs;
+
     /* Indexes */
+    struct ovsdb_idl_index *nbrec_mirror_by_type_and_sink;
     struct ovsdb_idl_index *sbrec_chassis_by_name;
     struct ovsdb_idl_index *sbrec_chassis_by_hostname;
     struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name;
     struct ovsdb_idl_index *sbrec_ip_mcast_by_dp;
     struct ovsdb_idl_index *sbrec_fdb_by_dp_and_port;
-    struct ovsdb_idl_index *nbrec_mirror_by_type_and_sink;
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type;
 };
 
 /* A collection of datapaths. E.g. all logical switch datapaths, or all
@@ -214,6 +218,10 @@ struct bfd_sync_data {
     struct sset bfd_ports;
 };
 
+struct ic_learned_svcs_data {
+    struct hmap ic_learned_svs;
+    struct lflow_ref *lflow_ref;
+};
 struct lflow_ref;
 struct lr_nat_table;
 
@@ -246,6 +254,8 @@ struct lflow_input {
     struct simap *route_tables;
     struct hmap *igmp_groups;
     struct lflow_ref *igmp_lflow_ref;
+    struct hmap *ic_learned_svcs;
+    struct lflow_ref *ic_leared_svcs_lflow_ref;
 };
 
 extern int parallelization_state;
@@ -860,6 +870,9 @@ void bfd_sync_init(struct bfd_sync_data *);
 void bfd_sync_swap(struct bfd_sync_data *, struct sset *bfd_ports);
 void bfd_sync_destroy(struct bfd_sync_data *);
 
+void ic_learned_svcs_init(struct ic_learned_svcs_data *data);
+void ic_learned_svcs_cleanup(struct ic_learned_svcs_data *data);
+
 struct lflow_table;
 struct lr_stateful_tracked_data;
 struct ls_stateful_tracked_data;
@@ -912,6 +925,9 @@ void bfd_table_sync(struct ovsdb_idl_txn *, const struct 
nbrec_bfd_table *,
                     struct sset *);
 void build_bfd_map(const struct nbrec_bfd_table *,
                    const struct sbrec_bfd_table *, struct hmap *);
+void build_ic_learned_svcs_map(struct hmap *ic_learned_svcs_map,
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type);
+
 void run_update_worker_pool(int n_threads);
 
 const struct ovn_datapath *northd_get_datapath_for_port(
diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
index 4c24f5b51..da1fd38e8 100644
--- a/ovn-sb.ovsschema
+++ b/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
 {
     "name": "OVN_Southbound",
-    "version": "21.2.0",
-    "cksum": "29145795 34859",
+    "version": "21.3.0",
+    "cksum": "3512532069 34910",
     "tables": {
         "SB_Global": {
             "columns": {
@@ -517,6 +517,7 @@
                 "src_mac": {"type": "string"},
                 "src_ip": {"type": "string"},
                 "chassis_name": {"type": "string"},
+                "ic_learned": {"type": "boolean"},
                 "status": {
                     "type": {"key": {"type": "string",
                              "enum": ["set", ["online", "offline", "error"]]},
diff --git a/ovn-sb.xml b/ovn-sb.xml
index db5faac66..f7eafd379 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -5010,6 +5010,11 @@ tcp.flags = RST;
         The name of the chassis where the logical port is bound.
       </column>
 
+      <column name="ic_learned">
+        Set to true if the service monitor was propagated from another
+        OVN deployment via ovn-ic management.
+      </column>
+
       <column name="options" key="interval" type='{"type": "integer"}'>
         The interval, in seconds, between service monitor checks.
       </column>
-- 
2.48.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to