The ofproto/detrace command wouldn't output anything when the cache
is empty. Add option to explicitly populate the cache when empty.

Signed-off-by: Ales Musil <[email protected]>
---
 ofproto/ofproto-dpif-upcall.c | 28 +++++++++++++++-----
 tests/ofproto-dpif.at         | 49 +++++++++++++++++++++++++++--------
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index e7d4c2b2c..2bafaa274 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -477,8 +477,9 @@ udpif_init(void)
                                  upcall_unixctl_pause, NULL);
         unixctl_command_register("revalidator/resume", NULL, 0, 0,
                                  upcall_unixctl_resume, NULL);
-        unixctl_command_register("ofproto/detrace", "UFID [pmd=PMD-ID]", 1, 2,
-                                 upcall_unixctl_ofproto_detrace, NULL);
+        unixctl_command_register("ofproto/detrace",
+                                 "[--populate-cache] UFID [pmd=PMD-ID]",
+                                 1, 3, upcall_unixctl_ofproto_detrace, NULL);
         ovsthread_once_done(&once);
     }
 }
@@ -3339,16 +3340,23 @@ upcall_unixctl_ofproto_detrace(struct unixctl_conn 
*conn, int argc,
                                const char *argv[], void *aux OVS_UNUSED)
 {
     unsigned int pmd_id = NON_PMD_CORE_ID;
-    const char *key_s = argv[1];
     ovs_u128 ufid;
+    int arg = 1;
 
+    bool populate_cache = false;
+    if (!strcmp(argv[arg], "--populate-cache")) {
+        populate_cache = true;
+        arg++;
+    }
+
+    const char *key_s = argv[arg++];
     if (odp_ufid_from_string(key_s, &ufid) <= 0) {
         unixctl_command_reply_error(conn, "failed to parse ufid");
         return;
     }
 
-    if (argc == 3) {
-        const char *pmd_str = argv[2];
+    if (arg < argc) {
+        const char *pmd_str = argv[arg++];
         if (!ovs_scan(pmd_str, "pmd=%d", &pmd_id)) {
             unixctl_command_reply_error(conn,
                                         "Invalid pmd argument format. "
@@ -3357,6 +3365,11 @@ upcall_unixctl_ofproto_detrace(struct unixctl_conn 
*conn, int argc,
         }
     }
 
+    if (arg != argc) {
+        unixctl_command_reply_error(conn, "Invalid arguments.");
+        return;
+    }
+
     struct ds ds = DS_EMPTY_INITIALIZER;
     struct udpif *udpif;
 
@@ -3369,8 +3382,9 @@ upcall_unixctl_ofproto_detrace(struct unixctl_conn *conn, 
int argc,
         ovs_mutex_lock(&ukey->mutex);
         /* It only makes sense to format rules for ukeys that are (still)
          * in use. */
-        if ((ukey->state == UKEY_VISIBLE || ukey->state == UKEY_OPERATIONAL)
-            && ukey->xcache) {
+        if ((ukey->state == UKEY_VISIBLE || ukey->state == UKEY_OPERATIONAL) &&
+            (ukey->xcache || (populate_cache &&
+            !populate_xcache(udpif, ukey, ukey->stats.tcp_flags)))) {
             xlate_xcache_format(&ds, ukey->xcache);
         }
         ovs_mutex_unlock(&ukey->mutex);
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 18bd359bf..7ca8df14e 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -12817,34 +12817,61 @@ table=4,ip,actions=p3
 AT_CHECK([ovs-ofctl add-groups br0 groups.txt])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-AT_CHECK([ovs-appctl netdev-dummy/receive p1 
'ipv4(src=10.0.0.1,dst=10.0.0.2,proto=6),tcp(src=1,dst=2)'])
 AT_CHECK([ovs-appctl netdev-dummy/receive p1 
'ipv4(src=10.0.0.1,dst=10.0.0.2,proto=6),tcp(src=1,dst=2)'])
 AT_CHECK([ovs-appctl revalidator/wait])
 AT_CHECK([ovs-appctl revalidator/pause])
 
 AT_CHECK([ovs-appctl dpctl/dump-flows | strip_used | strip_stats | 
strip_duration | strip_dp_hash | sort], [0], [dnl
 flow-dump from the main thread:
-recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no),
 packets:0, bytes:0, used:0.0s, actions:hash(l4(0)),recirc(0x1)
-recirc_id(0x1),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:0.0s, actions:ct(commit,nat(dst=20.0.0.2)),recirc(0x2)
-recirc_id(0x2),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:0.0s, actions:2,3
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no),
 packets:0, bytes:0, used:never, actions:hash(l4(0)),recirc(0x1)
+recirc_id(0x1),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:never, 
actions:ct(commit,nat(dst=20.0.0.2)),recirc(0x2)
+recirc_id(0x2),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:never, actions:2,3
 ])
 
 ufid=$(ovs-appctl dpctl/dump-flows -m filter='recirc_id(0)' | parse_ufid)
+
+# Check that the output is empty without populated cache.
+AT_CHECK([ovs-appctl ofproto/detrace $ufid | ofctl_strip], [0], [dnl
+])
+
+# Check the output when we request cache population.
+AT_CHECK([ovs-appctl ofproto/detrace --populate-cache $ufid | ofctl_strip], 
[0], [dnl
+cookie=0x12345678, n_packets=1, n_bytes=118, 
priority=100,ip,in_port=1,nw_dst=10.0.0.2,actions=resubmit(,1)
+table_id=1, n_packets=1, n_bytes=118, priority=200,ip,actions=group:1
+])
+
+# Check that it still outputs the expected result without as the cache should 
be populated.
 AT_CHECK([ovs-appctl ofproto/detrace $ufid | ofctl_strip], [0], [dnl
-cookie=0x12345678, n_packets=2, n_bytes=236, 
priority=100,ip,in_port=1,nw_dst=10.0.0.2,actions=resubmit(,1)
-table_id=1, n_packets=2, n_bytes=236, priority=200,ip,actions=group:1
+cookie=0x12345678, n_packets=1, n_bytes=118, 
priority=100,ip,in_port=1,nw_dst=10.0.0.2,actions=resubmit(,1)
+table_id=1, n_packets=1, n_bytes=118, priority=200,ip,actions=group:1
+])
+
+AT_CHECK([ovs-appctl revalidator/resume])
+AT_CHECK([ovs-appctl revalidator/purge])
+
+# Send two packets this time.
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 
'ipv4(src=10.0.0.1,dst=10.0.0.2,proto=6),tcp(src=1,dst=2)'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 
'ipv4(src=10.0.0.1,dst=10.0.0.2,proto=6),tcp(src=1,dst=2)'])
+AT_CHECK([ovs-appctl revalidator/wait])
+AT_CHECK([ovs-appctl revalidator/pause])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | strip_used | strip_stats | 
strip_duration | strip_dp_hash | sort], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.0.0.2,frag=no),
 packets:0, bytes:0, used:0.0s, actions:hash(l4(0)),recirc(0x3)
+recirc_id(0x3),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:0.0s, actions:ct(commit,nat(dst=20.0.0.2)),recirc(0x4)
+recirc_id(0x4),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
 packets:0, bytes:0, used:0.0s, actions:2,3
 ])
 
-ufid=$(ovs-appctl dpctl/dump-flows -m filter='recirc_id(0x1)' | parse_ufid)
+ufid=$(ovs-appctl dpctl/dump-flows -m filter='recirc_id(0x3)' | parse_ufid)
 AT_CHECK([ovs-appctl ofproto/detrace $ufid | ofctl_strip], [0], [dnl
 
group_id=1,type=select,selection_method=dp_hash,bucket=bucket_id:0,weight:100,actions=ct(commit,table=2,nat(dst=20.0.0.2))
 ])
 
-ufid=$(ovs-appctl dpctl/dump-flows -m filter='recirc_id(0x2)' | parse_ufid)
+ufid=$(ovs-appctl dpctl/dump-flows -m filter='recirc_id(0x4)' | parse_ufid)
 AT_CHECK([ovs-appctl ofproto/detrace $ufid | ofctl_strip], [0], [dnl
-table_id=2, n_packets=2, n_bytes=236, ip,actions=group:2
-table_id=3, n_packets=2, n_bytes=236, ip,actions=output:2
-table_id=4, n_packets=2, n_bytes=236, ip,actions=output:3
+table_id=2, n_packets=3, n_bytes=354, ip,actions=group:2
+table_id=3, n_packets=3, n_bytes=354, ip,actions=output:2
+table_id=4, n_packets=3, n_bytes=354, ip,actions=output:3
 
group_id=2,type=all,bucket=bucket_id:0,actions=resubmit(,3),bucket=bucket_id:1,actions=resubmit(,4)
 ])
 
-- 
2.47.0

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

Reply via email to