From 2fe34c03078f1fe01a39b4d963a9a367ba468bad Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Thu, 15 Oct 2020 11:33:59 +0800 Subject: [PATCH] dpctl: Add the option 'pmd' for dump-flows. "ovs-appctl dpctl/dump-flows" added the option "pmd" which allow user to dump pmd specified. That option is useful to dump rules of pmd when we have a large number of rules in dp. Signed-off-by: Tonghao Zhang Acked-by: Gaetan Rivet Signed-off-by: Ilya Maximets --- NEWS | 3 +++ lib/dpctl.c | 20 ++++++++++++++++---- lib/dpctl.man | 6 +++++- tests/pmd.at | 9 +++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index c0819bf93..a542c68ca 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ Post-v2.14.0 Use the 'cluster/set-backlog-threshold' command to change limits. - DPDK: * Removed support for vhost-user dequeue zero-copy. + - Userspace datapath: + * Add the 'pmd' option to "ovs-appctl dpctl/dump-flows", which + restricts a flow dump to a single PMD thread if set. - The environment variable OVS_UNBOUND_CONF, if set, is now used as the DNS resolver's (unbound) configuration file. - Linux datapath: diff --git a/lib/dpctl.c b/lib/dpctl.c index 2f859a753..33202813b 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -980,6 +980,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p) struct dpif_flow_dump *flow_dump; struct dpif_flow f; int pmd_id = PMD_ID_NULL; + bool pmd_id_filter = false; int lastargc = 0; int error; @@ -996,6 +997,16 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p) goto out_free; } types_list = xstrdup(argv[--argc] + 5); + } else if (!strncmp(argv[argc - 1], "pmd=", 4)) { + if (!ovs_scan(argv[--argc], "pmd=%d", &pmd_id)) { + error = EINVAL; + goto out_free; + } + + if (pmd_id == -1) { + pmd_id = NON_PMD_CORE_ID; + } + pmd_id_filter = true; } } @@ -1070,7 +1081,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p) /* If 'pmd_id' is specified, overlapping flows could be dumped from * different pmd threads. So, separates dumps from different pmds * by printing a title line. */ - if (pmd_id != f.pmd_id) { + if (!pmd_id_filter && pmd_id != f.pmd_id) { if (f.pmd_id == NON_PMD_CORE_ID) { ds_put_format(&ds, "flow-dump from the main thread:\n"); } else { @@ -1079,7 +1090,8 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p) } pmd_id = f.pmd_id; } - if (flow_passes_type_filter(&f, &dump_types)) { + if (pmd_id == f.pmd_id && + flow_passes_type_filter(&f, &dump_types)) { format_dpif_flow(&ds, &f, portno_names, dpctl_p); dpctl_print(dpctl_p, "%s\n", ds_cstr(&ds)); } @@ -2522,8 +2534,8 @@ static const struct dpctl_command all_commands[] = { { "set-if", "dp iface...", 2, INT_MAX, dpctl_set_if, DP_RW }, { "dump-dps", "", 0, 0, dpctl_dump_dps, DP_RO }, { "show", "[dp...]", 0, INT_MAX, dpctl_show, DP_RO }, - { "dump-flows", "[dp] [filter=..] [type=..]", - 0, 3, dpctl_dump_flows, DP_RO }, + { "dump-flows", "[dp] [filter=..] [type=..] [pmd=..]", + 0, 4, dpctl_dump_flows, DP_RO }, { "add-flow", "[dp] flow actions", 2, 3, dpctl_add_flow, DP_RW }, { "mod-flow", "[dp] flow actions", 2, 3, dpctl_mod_flow, DP_RW }, { "get-flow", "[dp] ufid", 1, 2, dpctl_get_flow, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 727d1f7be..0f6327786 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -104,7 +104,7 @@ default. When multiple datapaths exist, then a datapath name is required. . .TP -.DO "[\fB\-m \fR| \fB\-\-more\fR] [\fB\-\-names \fR| \fB\-\-no\-names\fR]" \*(DX\fBdump\-flows\fR "[\fIdp\fR] [\fBfilter=\fIfilter\fR] [\fBtype=\fItype\fR]" +.DO "[\fB\-m \fR| \fB\-\-more\fR] [\fB\-\-names \fR| \fB\-\-no\-names\fR]" \*(DX\fBdump\-flows\fR "[\fIdp\fR] [\fBfilter=\fIfilter\fR] [\fBtype=\fItype\fR] [\fBpmd=\fIpmd\fR]" Prints to the console all flow entries in datapath \fIdp\fR's flow table. Without \fB\-m\fR or \fB\-\-more\fR, output omits match fields that a flow wildcards entirely; with \fB\-m\fR or \fB\-\-more\fR, @@ -118,6 +118,10 @@ The \fIfilter\fR is also useful to match wildcarded fields in the datapath flow. As an example, \fBfilter='tcp,tp_src=100'\fR will match the datapath flow containing '\fBtcp(src=80/0xff00,dst=8080/0xff)\fR'. .IP +If \fBpmd=\fIpmd\fR is specified, only displays flows of the specified pmd. +Using \fBpmd=\fI-1\fR will restrict the dump to flows from the main thread. +This option is only supported by the \fBuserspace datapath\fR. +.IP If \fBtype=\fItype\fR is specified, only displays flows of the specified types. This option supported only for \fBovs\-appctl dpctl/dump\-flows\fR. \fItype\fR is a comma separated list, which can contain any of the following: diff --git a/tests/pmd.at b/tests/pmd.at index 5b612f88f..cc5371d5a 100644 --- a/tests/pmd.at +++ b/tests/pmd.at @@ -707,6 +707,15 @@ recirc_id(0),in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_typ recirc_id(0),in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x1234), packets:0, bytes:0, used:never, actions:2 ]) +dnl Check pmd filtering option. +AT_CHECK([ovs-appctl dpctl/dump-flows dummy@dp0 pmd=0], [0], [dnl +recirc_id(0),in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x1234), packets:0, bytes:0, used:never, actions:2 +]) + +AT_CHECK([ovs-appctl dpctl/dump-flows dummy@dp0 pmd=-1], [0], [dnl +recirc_id(0),in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x1234), packets:0, bytes:0, used:never, actions:2 +]) + AT_CHECK([ovs-appctl dpctl/del-flow dummy@dp0 'in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x1234)'], [0], [dnl ]) -- 2.39.2