Add logic to process logical switch port health checks in northd.

Signed-off-by: Alexandra Rukomoinikova <[email protected]>
---
v1 --> v2: fixed comments, removed all the unnecessary code from the previous 
version
           and made the code working with minimal changes.
           I will try to remove duplicate code in service monitor creation
           (Now we have almost the same code with creation for lb hc, nf hc and 
now in lsp hc)
           in the following patches.
---
 lib/ovn-util.c                   |  40 +++++++
 lib/ovn-util.h                   |   4 +
 northd/en-northd.c               |   2 +
 northd/inc-proc-northd.c         |   5 +-
 northd/northd.c                  | 190 +++++++++++++++++++++++++++----
 northd/northd.h                  |   3 +
 tests/ovn-inc-proc-graph-dump.at |   2 +
 tests/ovn-northd.at              |  91 +++++++++++++++
 8 files changed, 314 insertions(+), 23 deletions(-)

diff --git a/lib/ovn-util.c b/lib/ovn-util.c
index 1e754ac1c..9814e2d16 100644
--- a/lib/ovn-util.c
+++ b/lib/ovn-util.c
@@ -521,6 +521,46 @@ find_lport_address(const struct lport_addresses *laddrs, 
const char *ip_s)
     return NULL;
 }
 
+bool
+lport_addresses_contains_ip(const struct lport_addresses *lsp_addrs,
+                            unsigned int n_lsp_addrs,
+                            const char *ip_s)
+{
+    bool is_ipv4 = strchr(ip_s, '.') != NULL;
+    struct in6_addr ip6;
+    ovs_be32 ip4;
+
+    if (is_ipv4) {
+        if (!ip_parse(ip_s, &ip4)) {
+            return false;
+        }
+    } else {
+        if (!ipv6_parse(ip_s, &ip6)) {
+            return false;
+        }
+    }
+
+    for (size_t i = 0; i < n_lsp_addrs; i++) {
+        const struct lport_addresses *laddrs = &lsp_addrs[i];
+
+        if (is_ipv4) {
+            for (size_t j = 0; j < laddrs->n_ipv4_addrs; j++) {
+                if (laddrs->ipv4_addrs[j].addr == ip4) {
+                    return true;
+                }
+            }
+        } else {
+            for (size_t j = 0; j < laddrs->n_ipv6_addrs; j++) {
+                if (IN6_ARE_ADDR_EQUAL(&laddrs->ipv6_addrs[j].addr, &ip6)) {
+                    return true;
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
 /* Go through 'addresses' and add found IPv4 addresses to 'ipv4_addrs' and
  * IPv6 addresses to 'ipv6_addrs'. */
 void
diff --git a/lib/ovn-util.h b/lib/ovn-util.h
index 0ba0d1c26..1719caac4 100644
--- a/lib/ovn-util.h
+++ b/lib/ovn-util.h
@@ -130,6 +130,10 @@ const char *find_lport_address(const struct 
lport_addresses *laddrs,
 void split_addresses(const char *addresses, struct svec *ipv4_addrs,
                      struct svec *ipv6_addrs);
 
+bool lport_addresses_contains_ip(const struct lport_addresses *lport_address,
+                                 unsigned int n_lsp_addrs,
+                                 const char *ip_s);
+
 char *alloc_nat_zone_key(const char *name, const char *type);
 
 const char *default_nb_db(void);
diff --git a/northd/en-northd.c b/northd/en-northd.c
index 6815e6e39..9b37f3eee 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -82,6 +82,8 @@ northd_get_input_data(struct engine_node *node,
         EN_OVSDB_GET(engine_get_input("NB_network_function", node));
     input_data->nbrec_network_function_group_table =
         EN_OVSDB_GET(engine_get_input("NB_network_function_group", node));
+    input_data->nbrec_lsp_hc_table = EN_OVSDB_GET(engine_get_input(
+        "NB_logical_switch_port_health_check", node));
 
     input_data->sbrec_port_binding_table =
         EN_OVSDB_GET(engine_get_input("SB_port_binding", node));
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index 21e6aedcc..732066638 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -75,7 +75,8 @@ static unixctl_cb_func chassis_features_list;
     NB_NODE(chassis_template_var) \
     NB_NODE(sampling_app) \
     NB_NODE(network_function) \
-    NB_NODE(network_function_group)
+    NB_NODE(network_function_group) \
+    NB_NODE(logical_switch_port_health_check)
 
     enum nb_engine_node {
 #define NB_NODE(NAME) NB_##NAME,
@@ -256,6 +257,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_northd, &en_nb_chassis_template_var, NULL);
     engine_add_input(&en_northd, &en_nb_network_function, NULL);
     engine_add_input(&en_northd, &en_nb_network_function_group, NULL);
+    engine_add_input(&en_northd, &en_nb_logical_switch_port_health_check,
+                     NULL);
 
     engine_add_input(&en_northd, &en_sb_chassis, NULL);
     engine_add_input(&en_northd, &en_sb_mirror, NULL);
diff --git a/northd/northd.c b/northd/northd.c
index b4bb4ba6d..8cb307ca3 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3543,7 +3543,77 @@ build_lb_datapaths(const struct hmap *lbs, const struct 
hmap *lb_groups,
 }
 
 static void
-build_svcs(
+ovn_lsp_svc_monitors_process_port(struct ovsdb_idl_txn *ovnsb_txn,
+                                  const struct ovn_port *op,
+                                  const char *svc_monitor_mac,
+                                  const struct eth_addr *svc_monitor_mac_ea,
+                                  struct hmap *local_svc_monitors_map,
+                                  struct sset *svc_monitor_lsps)
+{
+    sset_add(svc_monitor_lsps, op->key);
+
+    for (size_t i = 0; i < op->nbsp->n_health_checks; i++) {
+        struct nbrec_logical_switch_port_health_check *lsp_hc =
+            op->nbsp->health_checks[i];
+        struct service_monitor_info *mon_info = NULL;
+
+        /* Check if this address is still on the port */
+        bool lsp_contain_ip =
+            lport_addresses_contains_ip(op->lsp_addrs, op->n_lsp_addrs,
+                                        lsp_hc->address);
+
+        /* Remove outdated records */
+        if (!lsp_contain_ip) {
+            mon_info = get_service_mon(local_svc_monitors_map,
+                                        NULL, lsp_hc->address,
+                                        op->key, lsp_hc->port,
+                                        lsp_hc->protocol);
+            if (mon_info) {
+                sbrec_service_monitor_delete(mon_info->sbrec_mon);
+                hmap_remove(local_svc_monitors_map, &mon_info->hmap_node);
+                free(mon_info);
+            }
+            continue;
+        }
+
+        mon_info = create_or_get_service_mon(ovnsb_txn,
+                                             local_svc_monitors_map,
+                                             NULL, "logical-switch-port",
+                                             lsp_hc->address, op->key, NULL,
+                                             lsp_hc->port, lsp_hc->protocol,
+                                             (op->sb && op->sb->chassis) ?
+                                              op->sb->chassis->name : NULL,
+                                             false);
+
+        mon_info->required = true;
+        set_service_mon_options(mon_info->sbrec_mon,
+                                &lsp_hc->options, NULL);
+
+        struct eth_addr ea;
+        if (!mon_info->sbrec_mon->src_mac ||
+            !eth_addr_from_string(mon_info->sbrec_mon->src_mac, &ea) ||
+            !eth_addr_equals(ea, *svc_monitor_mac_ea)) {
+            sbrec_service_monitor_set_src_mac(mon_info->sbrec_mon,
+                                                svc_monitor_mac);
+        }
+
+        if (!mon_info->sbrec_mon->src_ip ||
+            strcmp(mon_info->sbrec_mon->src_ip, lsp_hc->src_ip)) {
+            sbrec_service_monitor_set_src_ip(mon_info->sbrec_mon,
+                                                lsp_hc->src_ip);
+        }
+
+        if ((!op->sb->n_up || !op->sb->up[0]) &&
+            mon_info->sbrec_mon->status &&
+            !strcmp(mon_info->sbrec_mon->status, "online")) {
+            sbrec_service_monitor_set_status(mon_info->sbrec_mon,
+                                                "offline");
+        }
+    }
+}
+
+static void
+build_svc_monitors_data(
     struct ovsdb_idl_txn *ovnsb_txn,
     struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type,
     const char *svc_monitor_mac,
@@ -3555,7 +3625,8 @@ build_svcs(
     const struct nbrec_network_function_table *nbrec_network_function_table,
     struct sset *svc_monitor_lsps,
     struct hmap *local_svc_monitors_map,
-    struct hmap *ic_learned_svc_monitors_map)
+    struct hmap *ic_learned_svc_monitors_map,
+    struct hmapx *monitored_ports_map)
 {
     const struct sbrec_service_monitor *sbrec_mon;
     struct sbrec_service_monitor *key =
@@ -3605,6 +3676,18 @@ build_svcs(
         }
     }
 
+    struct hmapx_node *hmapx_node;
+    const struct ovn_port *op;
+    HMAPX_FOR_EACH (hmapx_node, monitored_ports_map) {
+        op = hmapx_node->data;
+        ovn_lsp_svc_monitors_process_port(ovnsb_txn,
+                                          op,
+                                          svc_monitor_mac,
+                                          svc_monitor_mac_ea,
+                                          local_svc_monitors_map,
+                                          svc_monitor_lsps);
+    }
+
     struct service_monitor_info *mon_info;
     HMAP_FOR_EACH_SAFE (mon_info, hmap_node, local_svc_monitors_map) {
         if (!mon_info->required) {
@@ -4084,6 +4167,16 @@ ovn_port_allocate_key(struct ovn_port *op)
     return true;
 }
 
+static inline void
+add_monitored_port(struct ovn_port *op, struct hmapx *monitored_ports_map)
+{
+    if (op->nbsp &&
+        op->nbsp->n_health_checks &&
+        lsp_is_enabled(op->nbsp)) {
+        hmapx_add(monitored_ports_map, op);
+    }
+}
+
 /* Updates the southbound Port_Binding table so that it contains the logical
  * switch ports specified by the northbound database.
  *
@@ -4100,7 +4193,8 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
     struct ovsdb_idl_index *sbrec_chassis_by_hostname,
     struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name,
     struct hmap *ls_datapaths, struct hmap *lr_datapaths,
-    struct hmap *ls_ports, struct hmap *lr_ports)
+    struct hmap *ls_ports, struct hmap *lr_ports,
+    struct hmapx *monitored_ports_map)
 {
     struct ovs_list sb_only, nb_only, both;
     /* XXX: Add tag_alloc_table and queue_id_bitmap as part of northd_data
@@ -4175,6 +4269,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
                               op, queue_id_bitmap,
                               &active_ha_chassis_grps);
         op->od->is_transit_router |= is_transit_router_port(op);
+        add_monitored_port(op, monitored_ports_map);
         ovs_list_remove(&op->list);
     }
 
@@ -4189,6 +4284,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
                               &active_ha_chassis_grps);
         sbrec_port_binding_set_logical_port(op->sb, op->key);
         op->od->is_transit_router |= is_transit_router_port(op);
+        add_monitored_port(op, monitored_ports_map);
         ovs_list_remove(&op->list);
     }
 
@@ -4370,6 +4466,11 @@ lsp_can_be_inc_processed(const struct 
nbrec_logical_switch_port *nbsp)
         }
     }
 
+     /* Attaching health check is not supported for now. */
+    if (nbsp->n_health_checks) {
+        return false;
+    }
+
     return true;
 }
 
@@ -15533,6 +15634,42 @@ build_arp_resolve_flows_for_lsp(
     }
 }
 
+static void
+build_arp_nd_lflow_for_lsp_svc_hc(struct ovn_port *op,
+                                  const char *svc_monitor_mac,
+                                  struct lflow_table *lflows,
+                                  struct ds *match,
+                                  struct ds *actions)
+{
+    const struct nbrec_logical_switch_port *nbsp = op->nbsp;
+    for (size_t i = 0; i < nbsp->n_health_checks; i++) {
+        struct nbrec_logical_switch_port_health_check *lsp_hc =
+            nbsp->health_checks[i];
+
+        /* Check if this address is still on the port */
+        bool lsp_contain_ip =
+            lport_addresses_contains_ip(op->lsp_addrs, op->n_lsp_addrs,
+                                        lsp_hc->address);
+
+        if (!lsp_contain_ip) {
+            continue;
+        }
+
+        ds_clear(match);
+        ds_clear(actions);
+
+        bool is_ipv4 = strchr(lsp_hc->src_ip, '.') ? true : false;
+
+        build_arp_nd_service_monitor_lflow(svc_monitor_mac,
+            lsp_hc->src_ip, actions, match, is_ipv4);
+
+        ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 110,
+                      ds_cstr(match), ds_cstr(actions),
+                      op->lflow_ref,
+                      WITH_HINT(&op->nbsp->header_));
+    }
+}
+
 #define ICMP4_NEED_FRAG_FORMAT                           \
     "icmp4_error {"                                      \
     "%s"                                                 \
@@ -19004,6 +19141,7 @@ build_lswitch_and_lrouter_iterate_by_lsp(struct 
ovn_port *op,
                                          const struct shash *meter_groups,
                                          struct ds *match,
                                          struct ds *actions,
+                                         const char *svc_monitor_mac,
                                          struct lflow_table *lflows)
 {
     ovs_assert(op->nbsp);
@@ -19027,6 +19165,8 @@ build_lswitch_and_lrouter_iterate_by_lsp(struct 
ovn_port *op,
 
     /* Build Logical Router Flows. */
     build_arp_resolve_flows_for_lsp(op, lflows, lr_ports, match, actions);
+    build_arp_nd_lflow_for_lsp_svc_hc(op, svc_monitor_mac, lflows,
+                                      match, actions);
 }
 
 /* Helper function to combine all lflow generation which is iterated by logical
@@ -19130,12 +19270,10 @@ build_lflows_thread(void *arg)
                     if (stop_parallel_processing()) {
                         return NULL;
                     }
-                    build_lswitch_and_lrouter_iterate_by_lsp(op, lsi->ls_ports,
-                                                             lsi->lr_ports,
-                                                             lsi->meter_groups,
-                                                             &lsi->match,
-                                                             &lsi->actions,
-                                                             lsi->lflows);
+                    build_lswitch_and_lrouter_iterate_by_lsp(
+                        op, lsi->ls_ports, lsi->lr_ports, lsi->meter_groups,
+                        &lsi->match, &lsi->actions, lsi->svc_monitor_mac,
+                        lsi->lflows);
                     build_lbnat_lflows_iterate_by_lsp(
                         op, lsi->lr_stateful_table, &lsi->match,
                         &lsi->actions, lsi->lflows);
@@ -19419,6 +19557,7 @@ build_lswitch_and_lrouter_flows(
                                                      lsi.meter_groups,
                                                      &lsi.match,
                                                      &lsi.actions,
+                                                     lsi.svc_monitor_mac,
                                                      lsi.lflows);
             build_lbnat_lflows_iterate_by_lsp(op, lsi.lr_stateful_table,
                                               &lsi.match,
@@ -19676,6 +19815,7 @@ lflow_handle_northd_port_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
                                                  lflow_input->lr_ports,
                                                  lflow_input->meter_groups,
                                                  &match, &actions,
+                                                 lflow_input->svc_monitor_mac,
                                                  lflows);
         /* Sync the new flows to SB. */
         bool handled = lflow_ref_sync_lflows(
@@ -19733,7 +19873,9 @@ lflow_handle_northd_port_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
         build_lswitch_and_lrouter_iterate_by_lsp(op, lflow_input->ls_ports,
                                                  lflow_input->lr_ports,
                                                  lflow_input->meter_groups,
-                                                 &match, &actions, lflows);
+                                                 &match, &actions,
+                                                 lflow_input->svc_monitor_mac,
+                                                 lflows);
 
         /* Sync the newly added flows to SB. */
         bool handled = lflow_ref_sync_lflows(
@@ -20436,6 +20578,7 @@ northd_init(struct northd_data *data)
     hmap_init(&data->lb_group_datapaths_map);
     sset_init(&data->svc_monitor_lsps);
     hmap_init(&data->local_svc_monitors_map);
+    hmapx_init(&data->monitored_ports_map);
     init_northd_tracked_data(data);
 }
 
@@ -20521,6 +20664,7 @@ northd_destroy(struct northd_data *data)
                                 &data->ls_ports, &data->lr_ports);
 
     sset_destroy(&data->svc_monitor_lsps);
+    hmapx_destroy(&data->monitored_ports_map);
     destroy_northd_tracked_data(data);
 }
 
@@ -20626,21 +20770,23 @@ ovnnb_db_run(struct northd_input *input_data,
                 input_data->sbrec_chassis_by_hostname,
                 input_data->sbrec_ha_chassis_grp_by_name,
                 &data->ls_datapaths.datapaths, &data->lr_datapaths.datapaths,
-                &data->ls_ports, &data->lr_ports);
+                &data->ls_ports, &data->lr_ports,
+                &data->monitored_ports_map);
     build_lb_port_related_data(&data->lr_datapaths, &data->ls_datapaths,
                                &data->lb_datapaths_map,
                                &data->lb_group_datapaths_map);
-    build_svcs(ovnsb_txn,
-               input_data->sbrec_service_monitor_by_learned_type,
-               input_data->svc_monitor_mac,
-               &input_data->svc_monitor_mac_ea,
-               input_data->svc_monitor_mac_dst,
-               input_data->svc_monitor_ip,
-               input_data->svc_monitor_ip_dst,
-               &data->ls_ports, &data->lb_datapaths_map,
-               input_data->nbrec_network_function_table,
-               &data->svc_monitor_lsps, &data->local_svc_monitors_map,
-               input_data->ic_learned_svc_monitors_map);
+    build_svc_monitors_data(ovnsb_txn,
+        input_data->sbrec_service_monitor_by_learned_type,
+        input_data->svc_monitor_mac,
+        &input_data->svc_monitor_mac_ea,
+        input_data->svc_monitor_mac_dst,
+        input_data->svc_monitor_ip,
+        input_data->svc_monitor_ip_dst,
+        &data->ls_ports, &data->lb_datapaths_map,
+        input_data->nbrec_network_function_table,
+        &data->svc_monitor_lsps, &data->local_svc_monitors_map,
+        input_data->ic_learned_svc_monitors_map,
+        &data->monitored_ports_map);
     build_lb_count_dps(&data->lb_datapaths_map);
     build_network_function_active(
         input_data->nbrec_network_function_group_table,
diff --git a/northd/northd.h b/northd/northd.h
index eb5c15f34..77e8b049b 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -44,6 +44,8 @@ struct northd_input {
     const struct nbrec_network_function_table *nbrec_network_function_table;
     const struct nbrec_network_function_group_table
         *nbrec_network_function_group_table;
+    const struct nbrec_logical_switch_port_health_check_table
+        *nbrec_lsp_hc_table;
 
     /* Southbound table references */
     const struct sbrec_port_binding_table *sbrec_port_binding_table;
@@ -203,6 +205,7 @@ struct northd_data {
     struct hmap lb_group_datapaths_map;
     struct sset svc_monitor_lsps;
     struct hmap local_svc_monitors_map;
+    struct hmapx monitored_ports_map;
 
     /* Change tracking data. */
     struct northd_tracked_data trk_data;
diff --git a/tests/ovn-inc-proc-graph-dump.at b/tests/ovn-inc-proc-graph-dump.at
index 3fe7b8fbd..ff2c8c0c7 100644
--- a/tests/ovn-inc-proc-graph-dump.at
+++ b/tests/ovn-inc-proc-graph-dump.at
@@ -18,6 +18,7 @@ digraph "Incremental-Processing-Engine" {
        NB_chassis_template_var [[style=filled, shape=box, fillcolor=white, 
label="NB_chassis_template_var"]];
        NB_network_function [[style=filled, shape=box, fillcolor=white, 
label="NB_network_function"]];
        NB_network_function_group [[style=filled, shape=box, fillcolor=white, 
label="NB_network_function_group"]];
+       NB_logical_switch_port_health_check [[style=filled, shape=box, 
fillcolor=white, label="NB_logical_switch_port_health_check"]];
        SB_chassis [[style=filled, shape=box, fillcolor=white, 
label="SB_chassis"]];
        SB_mirror [[style=filled, shape=box, fillcolor=white, 
label="SB_mirror"]];
        SB_meter [[style=filled, shape=box, fillcolor=white, label="SB_meter"]];
@@ -75,6 +76,7 @@ digraph "Incremental-Processing-Engine" {
        NB_chassis_template_var -> northd [[label=""]];
        NB_network_function -> northd [[label=""]];
        NB_network_function_group -> northd [[label=""]];
+       NB_logical_switch_port_health_check -> northd [[label=""]];
        SB_chassis -> northd [[label=""]];
        SB_mirror -> northd [[label=""]];
        SB_meter -> northd [[label=""]];
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 512e42036..2b46474fd 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -19359,3 +19359,94 @@ AT_CHECK([grep "ls1-to-spine" ls1flows | 
ovn_strip_lflows | sort], [0], [dnl
 
 OVN_CLEANUP_NORTHD
 AT_CLEANUP
+
+AT_SETUP([Logical Switch Port Health Check - lflow/service monitor 
synchronization])
+ovn_start
+
+check ovn-nbctl ls-add ls1
+check ovn-nbctl lsp-add ls1 lport1 -- \
+    lsp-set-addresses lport1 "f0:00:0f:01:02:04 192.168.0.10" 
"f0:00:0f:01:02:06 192.168.0.11"
+
+check ovn-nbctl set NB_Global . options:svc_monitor_mac="11:11:11:11:11:11"
+
+# Create service monitor for all lsp addresses.
+check ovn-nbctl lsp-hc-add lport1 icmp 192.168.0.255 192.168.0.10
+check ovn-nbctl lsp-hc-add lport1 icmp 192.168.0.255 192.168.0.11
+
+# Check lflow and service monitor synchronization
+AT_CHECK([ovn-sbctl lflow-list ls1 | grep 'ls_in_arp_rsp'| grep "priority=110" 
| ovn_strip_lflows], [0], [dnl
+  table=??(ls_in_arp_rsp      ), priority=110  , match=(arp.tpa == 
192.168.0.255 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 
11:11:11:11:11:11; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 
11:11:11:11:11:11; arp.tpa = arp.spa; arp.spa = 192.168.0.255; outport = 
inport; flags.loopback = 1; output;)
+])
+
+check_row_count sb:Service_Monitor 2
+check_column "false false" sb:Service_Monitor ic_learned logical_port=lport1
+check_column "false false" sb:Service_Monitor remote logical_port=lport1
+check_column "192.168.0.10 192.168.0.11" sb:Service_Monitor ip 
logical_port=lport1
+check_column "icmp icmp" sb:Service_Monitor protocol logical_port=lport1
+check_column "192.168.0.255 192.168.0.255" sb:Service_Monitor src_ip 
logical_port=lport1
+check_column "0 0" sb:Service_Monitor port logical_port=lport1
+check_column "logical-switch-port logical-switch-port" sb:Service_Monitor type 
logical_port=lport1
+check_column "11:11:11:11:11:11 11:11:11:11:11:11" sb:Service_Monitor src_mac 
logical_port=lport1
+
+# Create one more service monitor for all lsp addresses.
+check ovn-nbctl lsp-hc-add lport1 tcp 192.168.0.254 80 192.168.0.10
+check ovn-nbctl lsp-hc-add lport1 tcp 192.168.0.254 80 192.168.0.11
+
+AT_CHECK([ovn-sbctl lflow-list ls1 | grep 'ls_in_arp_rsp'| grep "priority=110" 
| ovn_strip_lflows], [0], [dnl
+  table=??(ls_in_arp_rsp      ), priority=110  , match=(arp.tpa == 
192.168.0.254 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 
11:11:11:11:11:11; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 
11:11:11:11:11:11; arp.tpa = arp.spa; arp.spa = 192.168.0.254; outport = 
inport; flags.loopback = 1; output;)
+  table=??(ls_in_arp_rsp      ), priority=110  , match=(arp.tpa == 
192.168.0.255 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 
11:11:11:11:11:11; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 
11:11:11:11:11:11; arp.tpa = arp.spa; arp.spa = 192.168.0.255; outport = 
inport; flags.loopback = 1; output;)
+])
+
+# Check options propogations
+hc_lport1_uuid=$(fetch_column nb:logical_switch_port_health_check _uuid 
address="192.168.0.10" protocol="tcp")
+
+check ovn-nbctl set logical_switch_port_health_check $hc_lport1_uuid 
options:interval=3
+check ovn-nbctl set logical_switch_port_health_check $hc_lport1_uuid 
options:timeout=30
+check ovn-nbctl set logical_switch_port_health_check $hc_lport1_uuid 
options:success_count=1
+check ovn-nbctl set logical_switch_port_health_check $hc_lport1_uuid 
options:failure_count=2
+
+sm_lport1_uuid=$(fetch_column sb:service_monitor _uuid protocol="tcp" 
ip="192.168.0.10")
+
+AT_CHECK([ovn-sbctl get Service_Monitor $sm_lport1_uuid options:interval],
+[0], ["3"
+])
+AT_CHECK([ovn-sbctl get Service_Monitor $sm_lport1_uuid options:failure_count],
+[0], ["2"
+])
+AT_CHECK([ovn-sbctl get Service_Monitor $sm_lport1_uuid options:success_count],
+[0], ["1"
+])
+AT_CHECK([ovn-sbctl get Service_Monitor $sm_lport1_uuid options:timeout],
+[0], ["30"
+])
+
+check ovn-nbctl lsp-del lport1
+check_row_count sb:Service_Monitor 0
+AT_CHECK([ovn-sbctl lflow-list ls1 | grep 'ls_in_arp_rsp'| grep "priority=110" 
| ovn_strip_lflows], [0], [dnl])
+
+# Create a port with health checks in one transaction - checking the 
processing of incremental processing
+check ovn-nbctl lsp-add ls1 lport1 -- \
+    lsp-set-addresses lport1 "f0:00:0f:01:02:04 192.168.0.10" 
"f0:00:0f:01:02:06 192.168.0.11" -- \
+    lsp-hc-add lport1 icmp 192.168.0.255 192.168.0.10 -- \
+    lsp-hc-add lport1 icmp 192.168.0.255 192.168.0.11
+
+check_row_count sb:Service_Monitor 2
+AT_CHECK([ovn-sbctl lflow-list ls1 | grep 'ls_in_arp_rsp'| grep "priority=110" 
| ovn_strip_lflows], [0], [dnl
+  table=??(ls_in_arp_rsp      ), priority=110  , match=(arp.tpa == 
192.168.0.255 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 
11:11:11:11:11:11; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 
11:11:11:11:11:11; arp.tpa = arp.spa; arp.spa = 192.168.0.255; outport = 
inport; flags.loopback = 1; output;)
+])
+
+check_row_count sb:Service_Monitor 2
+
+# Change the addresses on the switch port - expect records in SBDB to be 
deleted.
+lport1=$(fetch_column nb:logical_switch_port _uuid  name="lport1")
+check ovn-nbctl clear logical_switch_port $lport1 addresses
+
+check_row_count sb:Service_Monitor 0
+AT_CHECK([ovn-sbctl lflow-list ls1 | grep 'ls_in_arp_rsp'| grep "priority=110" 
| ovn_strip_lflows], [0], [])
+
+check ovn-nbctl lsp-set-addresses lport1 "f0:00:0f:01:02:04 192.168.0.10" 
"f0:00:0f:01:02:06 192.168.0.11"
+check_row_count sb:Service_Monitor 2
+
+AT_CLEANUP
+])
+
-- 
2.48.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to