diff mbox series

[ovs-dev] utilties: Allow ovn-detrace to run on ovs-ofctl dump-flows output.

Message ID 20240603082303.193454-1-amusil@redhat.com
State Accepted
Headers show
Series [ovs-dev] utilties: Allow ovn-detrace to run on ovs-ofctl dump-flows output. | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Ales Musil June 3, 2024, 8:23 a.m. UTC
The ovs-ofctl dump-flows output is slightly different from oproto/trace
cookie 0xXXX vs. cookie=0xXXX. Update the regex that it also matches
on the equals case. This allows us to run ovn-detrace against the
ovs-ofctl dump-flows output.

Also provide simple, partially hardcoded test case for ovn-detrace.

Signed-off-by: Ales Musil <amusil@redhat.com>
---
 tests/automake.mk           |   3 +-
 tests/ovn-util.at           | 108 ++++++++++++++++++++++++++++++++++++
 tests/testsuite.at          |   1 +
 utilities/ovn-debug.c       |  18 ++++++
 utilities/ovn_detrace.py.in |   5 +-
 5 files changed, 132 insertions(+), 3 deletions(-)
 create mode 100644 tests/ovn-util.at

Comments

Dumitru Ceara June 21, 2024, 2:29 p.m. UTC | #1
On 6/3/24 10:23, Ales Musil wrote:
> The ovs-ofctl dump-flows output is slightly different from oproto/trace
> cookie 0xXXX vs. cookie=0xXXX. Update the regex that it also matches
> on the equals case. This allows us to run ovn-detrace against the
> ovs-ofctl dump-flows output.
> 
> Also provide simple, partially hardcoded test case for ovn-detrace.
> 
> Signed-off-by: Ales Musil <amusil@redhat.com>
> ---

Looks good to me, thanks!

Acked-by: Dumitru Ceara <dceara@redhat.com>

Regards,
Dumitru
Dumitru Ceara June 28, 2024, 9:02 a.m. UTC | #2
On 6/21/24 16:29, Dumitru Ceara wrote:
> On 6/3/24 10:23, Ales Musil wrote:
>> The ovs-ofctl dump-flows output is slightly different from oproto/trace
>> cookie 0xXXX vs. cookie=0xXXX. Update the regex that it also matches
>> on the equals case. This allows us to run ovn-detrace against the
>> ovs-ofctl dump-flows output.
>>
>> Also provide simple, partially hardcoded test case for ovn-detrace.
>>
>> Signed-off-by: Ales Musil <amusil@redhat.com>
>> ---
> 
> Looks good to me, thanks!
> 
> Acked-by: Dumitru Ceara <dceara@redhat.com>
> 

I went ahead and applied this to main.  Thanks, Ales!

Regards,
Dumitru
diff mbox series

Patch

diff --git a/tests/automake.mk b/tests/automake.mk
index 1fdc89835..3899c9e80 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -45,7 +45,8 @@  TESTSUITE_AT = \
 	tests/ovn-lflow-cache.at \
 	tests/ovn-lflow-conj-ids.at \
 	tests/ovn-ipsec.at \
-	tests/ovn-vif-plug.at
+	tests/ovn-vif-plug.at \
+	tests/ovn-util.at
 
 SYSTEM_DPDK_TESTSUITE_AT = \
 	tests/system-dpdk-testsuite.at \
diff --git a/tests/ovn-util.at b/tests/ovn-util.at
new file mode 100644
index 000000000..fd3282548
--- /dev/null
+++ b/tests/ovn-util.at
@@ -0,0 +1,108 @@ 
+AT_SETUP([ovn-detrace - simple scenario])
+AT_SKIP_IF([test $HAVE_SCAPY = no])
+ovn_start
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int vm0 -- \
+    set interface vm0 external-ids:iface-id=vm0
+
+ovs-vsctl -- add-port br-int vm1 -- \
+    set interface vm1 external-ids:iface-id=vm1
+
+ovn-nbctl ls-add ls \
+    -- set logical_switch ls other-config:requested-tnl-key=1
+
+ovn-nbctl lsp-add ls vm0 \
+    -- lsp-set-addresses vm0 "f0:00:00:01:01:00 192.168.1.10" \
+    -- set logical_switch_port vm0 options:requested-tnl-key=10
+ovn-nbctl lsp-add ls vm1 \
+    -- lsp-set-addresses vm1 "f0:00:00:01:01:01 192.168.1.11" \
+    -- set logical_switch_port vm1 options:requested-tnl-key=11
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+wait_for_ports_up
+check ovn-nbctl --wait=hv sync
+
+ingress_table=$(ovn-debug lflow-stage-to-ltable ls_in_check_port_sec)
+egress_table=$(ovn-debug lflow-stage-to-ltable ls_out_apply_port_sec)
+dp_uuid=$(fetch_column datapath _uuid external_ids:name=ls)
+pb_vm0=$(ovn-debug uuid-to-cookie $(fetch_column port_binding _uuid \
+    logical_port=vm0))
+pb_vm1=$(ovn-debug uuid-to-cookie $(fetch_column port_binding _uuid \
+    logical_port=vm1))
+ingress=$(ovn-debug uuid-to-cookie $(fetch_column logical_flow _uuid \
+    table_id=$ingress_table pipeline=ingress match="1"))
+egress=$(ovn-debug uuid-to-cookie $(fetch_column logical_flow _uuid \
+    table_id=$egress_table pipeline=egress match="1"))
+
+cat << EOF > trace
+0. in_port=1, priority 100, cookie $pb_vm0
+set_field:0x4/0xffff->reg13
+set_field:0x1->reg11
+set_field:0x1->reg12
+set_field:0x1->metadata
+set_field:0x1->reg14
+set_field:0/0xffff0000->reg13
+resubmit(,??)
+8. metadata=0x1, priority 50, cookie $ingress
+set_field:0/0x1000->reg10
+resubmit(,??)
+51. metadata=0x1, priority 0, cookie $egress
+resubmit(,??)
+65. reg15=0x2,metadata=0x1, priority 100, cookie $pb_vm1
+output:2
+EOF
+
+AT_CHECK_UNQUOTED([cat trace | $PYTHON $top_srcdir/utilities/ovn_detrace.py.in], [0], [dnl
+0. in_port=1, priority 100, cookie $pb_vm0
+set_field:0x4/0xffff->reg13
+set_field:0x1->reg11
+set_field:0x1->reg12
+set_field:0x1->metadata
+set_field:0x1->reg14
+set_field:0/0xffff0000->reg13
+resubmit(,??)
+  * Logical datapath: "ls" ($dp_uuid)
+  * Port Binding: logical_port "vm0", tunnel_key 10, chassis-name "hv1", chassis-str "hv1"
+8. metadata=0x1, priority 50, cookie $ingress
+set_field:0/0x1000->reg10
+resubmit(,??)
+  * Logical datapaths:
+  *     "ls" ($dp_uuid) [[ingress]]
+  * Logical flow: table=$ingress_table (ls_in_check_port_sec), priority=50, match=(1), actions=(reg0[[15]] = check_in_port_sec(); next;)
+51. metadata=0x1, priority 0, cookie $egress
+resubmit(,??)
+  * Logical datapaths:
+  *     "ls" ($dp_uuid) [[egress]]
+  * Logical flow: table=$egress_table (ls_out_apply_port_sec), priority=0, match=(1), actions=(output;)
+65. reg15=0x2,metadata=0x1, priority 100, cookie $pb_vm1
+output:2
+  * Logical datapath: "ls" ($dp_uuid)
+  * Port Binding: logical_port "vm1", tunnel_key 11, chassis-name "hv1", chassis-str "hv1"
+
+])
+
+ovs-ofctl dump-flows br-int table=$(ovn-debug lflow-stage-to-oftable ls_in_check_port_sec),cookie=$ingress/0xffffffff >> flows
+ovs-ofctl dump-flows br-int table=$(ovn-debug lflow-stage-to-oftable ls_out_apply_port_sec),cookie=$egress/0xffffffff >> flows
+
+AT_CHECK_UNQUOTED([cat flows | awk '{print $1, $7, $8}' | grep -v "NXST_FLOW" | \
+                   sed -e "s/resubmit(,[[0-9]]\+)/resubmit(,??)/g" | \
+                   $PYTHON $top_srcdir/utilities/ovn_detrace.py.in], [0], [dnl
+cookie=$ingress, priority=50,metadata=0x1 actions=load:0->NXM_NX_REG10[[12]],resubmit(,??),move:NXM_NX_REG10[[12]]->NXM_NX_XXREG0[[111]],resubmit(,??)
+  * Logical datapaths:
+  *     "ls" ($dp_uuid) [[ingress]]
+  * Logical flow: table=$ingress_table (ls_in_check_port_sec), priority=50, match=(1), actions=(reg0[[15]] = check_in_port_sec(); next;)
+cookie=$egress, priority=0,metadata=0x1 actions=resubmit(,??)
+  * Logical datapaths:
+  *     "ls" ($dp_uuid) [[egress]]
+  * Logical flow: table=$egress_table (ls_out_apply_port_sec), priority=0, match=(1), actions=(output;)
+
+])
+
+OVN_CLEANUP([hv1])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d3f00e1bf..8e60bf82e 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -40,3 +40,4 @@  m4_include([tests/ovn-ic.at])
 m4_include([tests/checkpatch.at])
 m4_include([tests/ovn-ipsec.at])
 m4_include([tests/ovn-vif-plug.at])
+m4_include([tests/ovn-util.at])
diff --git a/utilities/ovn-debug.c b/utilities/ovn-debug.c
index 0cec9f671..0a0d2202b 100644
--- a/utilities/ovn-debug.c
+++ b/utilities/ovn-debug.c
@@ -76,6 +76,20 @@  lflow_stage_to_table(struct ovs_cmdl_context *ctx)
     exit(EXIT_SUCCESS);
 }
 
+static void
+uuid_to_cookie_str(struct ovs_cmdl_context *ctx)
+{
+    const char *uuid_str = ctx->argv[1];
+    struct uuid uuid = UUID_ZERO;
+
+    if (!uuid_from_string(&uuid, uuid_str)) {
+        ovs_fatal(0, "Couldn't convert UUID string \"%s\" to UUID", uuid_str);
+    }
+
+    printf("%#"PRIx32, uuid.parts[0]);
+    exit(EXIT_SUCCESS);
+}
+
 
 static void
 usage(void)
@@ -88,6 +102,8 @@  lflow-stage-to-ltable STAGE_NAME\n\
   Converts STAGE_NAME into logical flow table number.\n\
 lflow-stage-to-oftable STAGE_NAME\n\
   Converts STAGE_NAME into OpenFlow table number.\n\
+uuid-to-cookie UUID\n\
+  Converts UUID into cookie format.\n\
 \n\
 Options:\n\
   -h, --help                  display this help message\n\
@@ -145,6 +161,8 @@  main(int argc, char *argv[])
              OVS_RO},
             {"lflow-stage-to-ltable", NULL, 1, 1, lflow_stage_to_table,
              OVS_RO},
+            {"uuid-to-cookie", NULL, 1, 1, uuid_to_cookie_str,
+             OVS_RO},
             { "help", NULL, 0, INT_MAX, help, OVS_RO },
             {NULL, NULL, 0, 0, NULL, OVS_RO},
     };
diff --git a/utilities/ovn_detrace.py.in b/utilities/ovn_detrace.py.in
index 12df6e52a..986c5b8ad 100755
--- a/utilities/ovn_detrace.py.in
+++ b/utilities/ovn_detrace.py.in
@@ -515,7 +515,7 @@  def main():
     printer = Printer()
     cookie_handlers = get_cookie_handlers(ovsdb_ovnnb, ovsdb_ovnsb, printer)
 
-    regex_cookie = re.compile(r'^.*cookie 0x([0-9a-fA-F]+)')
+    regex_cookie = re.compile(r'^.*cookie[ =]0x([0-9a-fA-F]+)')
     regex_handlers = [
         (regex_cookie, cookie_handlers)
     ]
@@ -537,7 +537,8 @@  def main():
         line = sys.stdin.readline()
         if len(cookies) > 0:
             # Print record info when the current flow block ends.
-            if regex_table_id.match(line) or line.strip() == '':
+            if regex_table_id.match(line) or line.strip() == '' or \
+                regex_cookie.match(line):
                 for cookie, handlers in cookies:
                     print_record_from_cookie(ovsdb_ovnnb, handlers, cookie)
                 cookies = []