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
