This commit adds a new optional svc_monitor_ipv4 config in the NB_Global
options column. This IP address can be used to send the packets to the
OVN controller bypassing most of the logical switches pipelines.

Usage: Currently Load balancer health check requires a source IP address
to be allocated from the subnets where backends are present.
This change removes that requirement and instead user can give one IP
address for the system and set it in NB_Global:options:svc_monitor_ipv4.
While configuring the health check for the load balancer user can
provide this same IP while specifying the ip-port mappings.

Signed-off-by: Priyankar Jain <priyankar.j...@nutanix.com>
---

Changes since v1:
 - Fixed one testcase in ovn-northd.at

---
 northd/en-sync-sb.c     | 10 +++++
 northd/northd.c         | 34 +++++++++++++--
 northd/northd.h         |  1 +
 northd/ovn-northd.8.xml | 40 +++++++++++------
 tests/ovn-northd.at     | 96 ++++++++++++++++++++---------------------
 5 files changed, 116 insertions(+), 65 deletions(-)

diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c
index 2ec3bf54f..95e9ead29 100644
--- a/northd/en-sync-sb.c
+++ b/northd/en-sync-sb.c
@@ -372,6 +372,16 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn,
     sync_addr_set(ovnsb_txn, "svc_monitor_mac", &svc, &sb_address_sets);
     sorted_array_destroy(&svc);
 
+    /* Service monitor IP. */
+    const char *svc_monitor_ip4 = northd_get_svc_monitor_ip4();
+    int num_addr = 0; /* Create empty address-set by default */
+    if (svc_monitor_ip4) {
+        num_addr = 1;
+    }
+    struct sorted_array ip_svc = sorted_array_create(&svc_monitor_ip4,
+                                                     num_addr, false);
+    sync_addr_set(ovnsb_txn, "svc_monitor_ip4", &ip_svc, &sb_address_sets);
+
     /* sync port group generated address sets first */
     const struct nbrec_port_group *nb_port_group;
     NBREC_PORT_GROUP_TABLE_FOR_EACH (nb_port_group,
diff --git a/northd/northd.c b/northd/northd.c
index db3cd272e..f6d35143a 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -82,6 +82,7 @@ static bool use_common_zone = false;
 static char svc_monitor_mac[ETH_ADDR_STRLEN + 1];
 static struct eth_addr svc_monitor_mac_ea;
 
+static char *svc_monitor_ip4 = NULL;
 /* If this option is 'true' northd will make use of ct.inv match fields.
  * Otherwise, it will avoid using it.  The default is true. */
 static bool use_ct_inv_match = true;
@@ -7197,7 +7198,8 @@ build_pre_acls(struct ovn_datapath *od,
     ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 0, "1", "next;");
 
     ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 110,
-                  "eth.dst == $svc_monitor_mac", "next;");
+                  "eth.dst == $svc_monitor_mac || ip4.dst == $svc_monitor_ip4",
+                  "next;");
 
     ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110,
                   "eth.src == $svc_monitor_mac", "next;");
@@ -7370,7 +7372,8 @@ build_pre_lb(struct ovn_datapath *od, const struct shash 
*meter_groups,
 
     /* Do not send service monitor packets to conntrack. */
     ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_LB, 110,
-                  "eth.dst == $svc_monitor_mac", "next;");
+                  "eth.dst == $svc_monitor_mac || ip4.dst == $svc_monitor_ip4",
+                  "next;");
     ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_LB, 110,
                   "eth.src == $svc_monitor_mac", "next;");
 
@@ -8238,7 +8241,7 @@ build_acls(struct ovn_datapath *od, const struct 
chassis_features *features,
         /* Add a 34000 priority flow to advance the service monitor reply
         * packets to skip applying ingress ACLs. */
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_EVAL, 34000,
-                    "eth.dst == $svc_monitor_mac",
+                    "eth.dst == $svc_monitor_mac || ip4.dst == 
$svc_monitor_ip4",
                     REGBIT_ACL_VERDICT_ALLOW" = 1; next;");
 
         /* Add a 34000 priority flow to advance the service monitor packets
@@ -10325,7 +10328,8 @@ build_lswitch_destination_lookup_bmcast(struct 
ovn_datapath *od,
     ovs_assert(od->nbs);
 
     ovn_lflow_metered(lflows, od, S_SWITCH_IN_L2_LKUP, 110,
-                      "eth.dst == $svc_monitor_mac && (tcp || icmp || icmp6)",
+                      "(eth.dst == $svc_monitor_mac || ip4.dst == 
$svc_monitor_ip4)"
+                      " && (tcp || icmp || icmp6)",
                       "handle_svc_check(inport);",
                       copp_meter_get(COPP_SVC_MONITOR, od->nbs->copp,
                                      meter_groups));
@@ -17891,6 +17895,22 @@ ovnnb_db_run(struct northd_input *input_data,
         smap_replace(&options, "svc_monitor_mac", svc_monitor_mac);
     }
 
+    const char *monitor_ip4 = smap_get(&nb->options, "svc_monitor_ip4");
+    if (monitor_ip4) {
+        struct sockaddr_storage svc_mon_src_addr;
+        if (inet_parse_address(monitor_ip4, &svc_mon_src_addr)) {
+            struct ds src_ip_s = DS_EMPTY_INITIALIZER;
+            ss_format_address_nobracks(&svc_mon_src_addr, &src_ip_s);
+            svc_monitor_ip4 = ds_steal_cstr(&src_ip_s);
+        } else {
+            free(svc_monitor_ip4);
+            svc_monitor_ip4 = NULL;
+        }
+    } else {
+        free(svc_monitor_ip4);
+        svc_monitor_ip4 = NULL;
+    }
+
     char *max_tunid = xasprintf("%d",
         get_ovn_max_dp_key_local(input_data->sbrec_chassis_table));
     smap_replace(&options, "max_tunid", max_tunid);
@@ -18326,3 +18346,9 @@ northd_get_datapath_for_port(const struct hmap 
*ls_ports,
 
     return op ? op->od : NULL;
 }
+
+const char *
+northd_get_svc_monitor_ip4(void)
+{
+    return svc_monitor_ip4;
+}
diff --git a/northd/northd.h b/northd/northd.h
index 5be7b5384..a69b96bda 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -374,4 +374,5 @@ bool check_sb_lb_duplicates(const struct 
sbrec_load_balancer_table *);
 void sync_pbs(struct ovsdb_idl_txn *, struct hmap *ls_ports);
 bool sync_pbs_for_northd_ls_changes(struct tracked_ls_changes *);
 
+const char *northd_get_svc_monitor_ip4(void);
 #endif /* NORTHD_H */
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 98cf7adb4..c121fbb4c 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -448,11 +448,14 @@
 
     <p>
       This table also has a priority-110 flow with the match
-      <code>eth.dst == <var>E</var></code> for all logical switch
-      datapaths to move traffic to the next table. Where <var>E</var>
-      is the service monitor mac defined in the
+      <code>eth.dst == <var>E</var> || ip4.dst == <var>I</var></code> for all
+      logical switch datapaths to move traffic to the next table. Where
+      <var>E</var> is the service monitor mac defined in the
       <ref column="options:svc_monitor_mac" table="NB_Global"
       db="OVN_Northbound"/> column of <ref table="NB_Global"
+      db="OVN_Northbound"/> table and <var>I</var> is the service monitor
+      IP defined in the <ref column="options:svc_monitor_ip4" table="NB_Global"
+      db="OVN_Northbound"/> column of <ref table="NB_Global"
       db="OVN_Northbound"/> table.
     </p>
 
@@ -515,11 +518,14 @@
 
     <p>
       This table also has a priority-110 flow with the match
-      <code>eth.dst == <var>E</var></code> for all logical switch
-      datapaths to move traffic to the next table. Where <var>E</var>
-      is the service monitor mac defined in the
+      <code>eth.dst == <var>E</var> || ip4.dst == <var>I</var></code> for all
+      logical switch datapaths to move traffic to the next table. Where
+      <var>E</var> is the service monitor mac defined in the
       <ref column="options:svc_monitor_mac" table="NB_Global"
       db="OVN_Northbound"/> column of <ref table="NB_Global"
+      db="OVN_Northbound"/> table and <var>I</var> is the service monitor
+      IP defined in the <ref column="options:svc_monitor_ip4" table="NB_Global"
+      db="OVN_Northbound"/> column of <ref table="NB_Global"
       db="OVN_Northbound"/> table.
     </p>
 
@@ -820,12 +826,15 @@
     <ul>
       <li>
         A priority 34000 logical flow is added for each logical switch datapath
-        with the match <code>eth.dst = <var>E</var></code> to allow the service
-        monitor reply packet destined to <code>ovn-controller</code>
-        that sets the allow bit, where <var>E</var> is the
-        service monitor mac defined in the
+        with the match <code>eth.dst = <var>E</var> || ip4.dst == <var>I</var>
+        </code> to allow the service monitor reply packet destined to
+        <code>ovn-controller</code> that sets the allow bit, where <var>E</var>
+        is the service monitor mac defined in the
         <ref column="options:svc_monitor_mac" table="NB_Global"
         db="OVN_Northbound"/> column of <ref table="NB_Global"
+        db="OVN_Northbound"/> table and <var>I</var> is the service monitor IP
+        defined in the <ref column="options:svc_monitor_ip4" table="NB_Global"
+        db="OVN_Northbound"/> column of <ref table="NB_Global"
         db="OVN_Northbound"/> table.
       </li>
     </ul>
@@ -1883,11 +1892,16 @@ output;
     <ul>
       <li>
         A priority-110 flow with the match
-        <code>eth.src == <var>E</var></code> for all logical switch
-        datapaths and applies the action <code>handle_svc_check(inport)</code>.
-        Where <var>E</var> is the service monitor mac defined in the
+        <code>eth.src == <var>E</var> || ip4.dst == <var>I</var></code> for
+        all logical switch datapaths and applies the action
+        <code>handle_svc_check(inport)</code>. Where <var>E</var> is the
+        service monitor mac defined in the
         <ref column="options:svc_monitor_mac" table="NB_Global"
         db="OVN_Northbound"/> column of <ref table="NB_Global"
+        db="OVN_Northbound"/> table and <var>I</var> is the
+        service monitor IP defined in the
+        <ref column="options:svc_monitor_ip4" table="NB_Global"
+        db="OVN_Northbound"/> column of <ref table="NB_Global"
         db="OVN_Northbound"/> table.
       </li>
 
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 34bd25de7..dcb2e514c 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -2611,7 +2611,7 @@ AT_CHECK([ovn-sbctl lflow-list ls | grep -e 
ls_in_acl_hint -e ls_out_acl_hint -e
   table=8 (ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && 
ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
   table=8 (ls_in_acl_eval     ), priority=1001 , match=(reg0[[7]] == 1 && 
(ip)), action=(reg8[[16]] = 1; reg0[[1]] = 1; next;)
   table=8 (ls_in_acl_eval     ), priority=1001 , match=(reg0[[8]] == 1 && 
(ip)), action=(reg8[[16]] = 1; next;)
-  table=8 (ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=8 (ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=8 (ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=8 (ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=8 (ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -4318,7 +4318,7 @@ check_stateful_flows() {
     AT_CHECK([grep "ls_in_pre_lb" sw0flows | sort | sed 's/table=./table=?/'], 
[0], [dnl
   table=? (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
   table=? (ls_in_pre_lb       ), priority=100  , match=(ip), action=(reg0[[2]] 
= 1; next;)
-  table=? (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=? (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(eth.mcast), 
action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(ip && inport == 
"sw0-lr0"), action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra 
|| mldv1 || mldv2), action=(next;)
@@ -4388,7 +4388,7 @@ AT_CAPTURE_FILE([sw0flows])
 
 AT_CHECK([grep "ls_in_pre_lb" sw0flows | sort | sed 's/table=./table=?/'], 
[0], [dnl
   table=? (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
-  table=? (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=? (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(eth.mcast), 
action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(ip && inport == 
"sw0-lr0"), action=(next;)
   table=? (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra 
|| mldv1 || mldv2), action=(next;)
@@ -5079,7 +5079,7 @@ check ovn-nbctl --wait=sb sync
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5091,7 +5091,7 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 
's/table=../table=??/' | sort],
 ovn-sbctl lflow-list ls2 > ls2_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:02), action=(outport = "vm2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5111,7 +5111,7 @@ check ovn-nbctl --wait=sb lr-nat-add ro2 snat 20.0.0.200 
192.168.2.200/30
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5125,7 +5125,7 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 
's/table=../table=??/' | sort],
 ovn-sbctl lflow-list ls2 > ls2_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:02), action=(outport = "vm2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5147,7 +5147,7 @@ check ovn-nbctl --wait=sb lr-nat-add ro2 snat 40.0.0.200 
192.168.2.148/30
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5163,7 +5163,7 @@ AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 
's/table=../table=??/' | sort],
 ovn-sbctl lflow-list ls2 > ls2_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls2_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:01), action=(outport = "ls2-ro2"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:02:02), action=(outport = "vm2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5184,7 +5184,7 @@ ovn-nbctl --wait=sb lr-lb-add ro1 lb1
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5204,7 +5204,7 @@ ovn-nbctl --wait=sb lb-add lb1 192.168.4.100:80 
10.0.0.10:80
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -5230,7 +5230,7 @@ ovn-nbctl --wait=sb lrp-set-gateway-chassis ro1-ls1 
chassis-1 30
 ovn-sbctl lflow-list ls1 > ls1_lflows
 AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | 
sort], [0], [dnl
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:01), action=(outport = "ls1-ro1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:01:02), action=(outport = "vm1"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -7172,7 +7172,7 @@ AT_CHECK([grep -e "ls_in_acl.*eval" -e "ls_in_acl_hint" 
lsflows | sed 's/table=.
   table=??(ls_in_acl_eval     ), priority=2003 , match=(reg0[[8]] == 1 && (ip4 
&& icmp)), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=2004 , match=(reg0[[10]] == 1 && 
(ip4 && ip4.dst == 10.0.0.2)), action=(reg8[[17]] = 1; ct_commit { 
ct_mark.blocked = 1; }; next;)
   table=??(ls_in_acl_eval     ), priority=2004 , match=(reg0[[9]] == 1 && (ip4 
&& ip4.dst == 10.0.0.2)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -7227,7 +7227,7 @@ AT_CHECK([grep -e "ls_in_acl.*eval" -e "ls_in_acl_hint" 
lsflows | sed 's/table=.
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && !ct.est), 
action=(reg0[[1]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && 
ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -7282,7 +7282,7 @@ AT_CHECK([grep -e "ls_in_acl.*eval" -e "ls_in_acl_hint" 
lsflows | sed 's/table=.
   table=??(ls_in_acl_eval     ), priority=2002 , match=(reg0[[8]] == 1 && (ip4 
&& tcp)), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=2003 , match=(reg0[[7]] == 1 && (ip4 
&& icmp)), action=(reg8[[16]] = 1; reg0[[1]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=2003 , match=(reg0[[8]] == 1 && (ip4 
&& icmp)), action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -7573,7 +7573,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_acl_hint     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(next;)
   table=??(ls_out_acl_eval    ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_out_acl_eval    ), priority=65535, match=(1), action=(next;)
@@ -7598,7 +7598,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_acl_hint     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(next;)
   table=??(ls_out_acl_eval    ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_out_acl_eval    ), priority=65535, match=(1), action=(next;)
@@ -7623,7 +7623,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_acl_hint     ), priority=65535, match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(next;)
   table=??(ls_out_acl_eval    ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_out_acl_eval    ), priority=65535, match=(1), action=(next;)
@@ -7656,11 +7656,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7693,11 +7693,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7730,11 +7730,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7771,7 +7771,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && 
ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=1001 , match=(reg0[[7]] == 1 && (ip4 
&& tcp)), action=(reg8[[16]] = 1; reg0[[1]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=1001 , match=(reg0[[8]] == 1 && (ip4 
&& tcp)), action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -7786,7 +7786,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_hint     ), priority=7    , match=(ct.new && !ct.est), 
action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=100  , match=(ip), action=(reg0[[0]] 
= 1; next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(eth.mcast), 
action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(nd || nd_rs || nd_ra 
|| mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7840,11 +7840,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7877,11 +7877,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7914,11 +7914,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=1001 , match=((ip4 && tcp)), 
action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -7955,7 +7955,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && !ct.est), 
action=(next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && 
ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -7970,7 +7970,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_hint     ), priority=7    , match=(ct.new && !ct.est), 
action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=100  , match=(ip), action=(reg0[[0]] 
= 1; next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(eth.mcast), 
action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(nd || nd_rs || nd_ra 
|| mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -8023,11 +8023,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -8060,11 +8060,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -8097,11 +8097,11 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_after_lb_eval), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || 
nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs 
|| mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[16]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; next;)
   table=??(ls_out_acl_action  ), priority=1000 , match=(reg8[[17]] == 1), 
action=(reg8[[16]] = 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -8137,7 +8137,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_eval     ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && !ct.est), 
action=(next;)
   table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && 
ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac), action=(reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=34000, match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && 
!ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] 
= 1; ct_commit_nat;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && 
!ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; 
reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && 
ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
@@ -8152,7 +8152,7 @@ AT_CHECK([ovn-sbctl dump-flows | grep -E "ls_.*_acl" | 
sed 's/table=../table=??/
   table=??(ls_in_acl_hint     ), priority=7    , match=(ct.new && !ct.est), 
action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
   table=??(ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
   table=??(ls_in_pre_acl      ), priority=100  , match=(ip), action=(reg0[[0]] 
= 1; next;)
-  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac), action=(next;)
+  table=??(ls_in_pre_acl      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4), action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(eth.mcast), 
action=(next;)
   table=??(ls_in_pre_acl      ), priority=110  , match=(nd || nd_rs || nd_ra 
|| mldv1 || mldv2 || (udp && udp.src == 546 && udp.dst == 547)), action=(next;)
   table=??(ls_out_acl_action  ), priority=0    , match=(1), action=(reg8[[16]] 
= 0; reg8[[17]] = 0; reg8[[18]] = 0; /* drop */)
@@ -8324,7 +8324,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
   table=??(ls_in_l2_unknown   ), priority=0    , match=(1), action=(output;)
   table=??(ls_in_l2_unknown   ), priority=50   , match=(outport == "none"), 
action=(drop;)
@@ -8349,7 +8349,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:01), action=(outport = "sw0p1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:02), action=(outport = "sw0p2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -8375,7 +8375,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:01), action=(outport = "sw0p1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:02), action=(outport = "sw0p2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -8402,7 +8402,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=0    , match=(1), action=(output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:01), action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:02), action=(outport = "sw0p2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -8430,7 +8430,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=110  , match=(outport == 
"localnetport" && inport == "sw0p2"), action=(set_queue(10); output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:01), action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:02), action=(outport = "sw0p2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
@@ -8462,7 +8462,7 @@ sort | sed 's/table=../table=??/' ], [0], [dnl
   table=??(ls_out_apply_port_sec), priority=110  , match=(outport == 
"localnetport" && inport == "sw0p2"), action=(set_queue(10); output;)
   table=??(ls_out_apply_port_sec), priority=50   , match=(reg0[[15]] == 1), 
action=(drop;)
   table=??(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = 
get_fdb(eth.dst); next;)
-  table=??(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == 
$svc_monitor_mac && (tcp || icmp || icmp6)), action=(handle_svc_check(inport);)
+  table=??(ls_in_l2_lkup      ), priority=110  , match=((eth.dst == 
$svc_monitor_mac || ip4.dst == $svc_monitor_ip4) && (tcp || icmp || icmp6)), 
action=(handle_svc_check(inport);)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:01), action=(outport = "sw0p1"; output;)
   table=??(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 
00:00:00:00:00:02), action=(outport = "sw0p2"; output;)
   table=??(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), 
action=(outport = "_MC_flood"; output;)
-- 
2.39.2 (Apple Git-143)

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

Reply via email to