summaryrefslogtreecommitdiff
path: root/lib/dpctl.c
diff options
context:
space:
mode:
authorGavi Teitz <gavi@mellanox.com>2018-07-08 14:15:38 +0300
committerSimon Horman <simon.horman@netronome.com>2018-07-25 18:16:27 +0200
commitab15e70eb5878b46f8f84da940ffc915b6d74cad (patch)
tree4aa609700e3501c5762783d098a6f32a0398df8a /lib/dpctl.c
parentf9885dc594c1ac93f4f1c1b4cc215c1f20d587ec (diff)
downloadopenvswitch-ab15e70eb5878b46f8f84da940ffc915b6d74cad.tar.gz
dpctl: Expand the flow dump type filter
Added new types to the flow dump filter, and allowed multiple filter types to be passed at once, as a comma separated list. The new types added are: * tc - specifies flows handled by the tc dp * non-offloaded - specifies flows not offloaded to the HW * all - specifies flows of all types The type list is now fully parsed by the dpctl, and a new struct was added to dpif which enables dpctl to define which types of dumps to provide, rather than passing the type string and having dpif parse it. Signed-off-by: Gavi Teitz <gavi@mellanox.com> Acked-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Simon Horman <simon.horman@netronome.com>
Diffstat (limited to 'lib/dpctl.c')
-rw-r--r--lib/dpctl.c107
1 files changed, 82 insertions, 25 deletions
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 4f1e443f2..9e504c9d1 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -792,18 +792,80 @@ format_dpif_flow(struct ds *ds, const struct dpif_flow *f, struct hmap *ports,
format_odp_actions(ds, f->actions, f->actions_len, ports);
}
-static char *supported_dump_types[] = {
- "offloaded",
- "ovs",
+struct dump_types {
+ bool ovs;
+ bool tc;
+ bool offloaded;
+ bool non_offloaded;
};
+static void
+enable_all_dump_types(struct dump_types *dump_types)
+{
+ dump_types->ovs = true;
+ dump_types->tc = true;
+ dump_types->offloaded = true;
+ dump_types->non_offloaded = true;
+}
+
+static int
+populate_dump_types(char *types_list, struct dump_types *dump_types,
+ struct dpctl_params *dpctl_p)
+{
+ if (!types_list) {
+ enable_all_dump_types(dump_types);
+ return 0;
+ }
+
+ char *current_type;
+ while (types_list && types_list[0] != '\0') {
+ current_type = types_list;
+ size_t type_len = strcspn(current_type, ",");
+ types_list += type_len + (types_list[type_len] != '\0');
+ current_type[type_len] = '\0';
+
+ if (!strcmp(current_type, "ovs")) {
+ dump_types->ovs = true;
+ } else if (!strcmp(current_type, "tc")) {
+ dump_types->tc = true;
+ } else if (!strcmp(current_type, "offloaded")) {
+ dump_types->offloaded = true;
+ } else if (!strcmp(current_type, "non-offloaded")) {
+ dump_types->non_offloaded = true;
+ } else if (!strcmp(current_type, "all")) {
+ enable_all_dump_types(dump_types);
+ } else {
+ dpctl_error(dpctl_p, EINVAL, "Failed to parse type (%s)", current_type);
+ return EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void
+determine_dpif_flow_dump_types(struct dump_types *dump_types,
+ struct dpif_flow_dump_types *dpif_dump_types) {
+ dpif_dump_types->ovs_flows = dump_types->ovs || dump_types->non_offloaded;
+ dpif_dump_types->netdev_flows = dump_types->tc || dump_types->offloaded
+ || dump_types->non_offloaded;
+}
+
static bool
-flow_passes_type_filter(const struct dpif_flow *f, char *type)
+flow_passes_type_filter(const struct dpif_flow *f, struct dump_types *dump_types)
{
- if (!strcmp(type, "offloaded")) {
- return f->attrs.offloaded;
+ if (dump_types->ovs && !strcmp(f->attrs.dp_layer, "ovs")) {
+ return true;
+ }
+ if (dump_types->tc && !strcmp(f->attrs.dp_layer, "tc")) {
+ return true;
+ }
+ if (dump_types->offloaded && f->attrs.offloaded) {
+ return true;
+ }
+ if (dump_types->non_offloaded && !(f->attrs.offloaded)) {
+ return true;
}
- return true;
+ return false;
}
static struct hmap *
@@ -843,9 +905,11 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
struct ds ds;
char *filter = NULL;
- char *type = NULL;
struct flow flow_filter;
struct flow_wildcards wc_filter;
+ char *types_list = NULL;
+ struct dump_types dump_types;
+ struct dpif_flow_dump_types dpif_dump_types;
struct dpif_flow_dump_thread *flow_dump_thread;
struct dpif_flow_dump *flow_dump;
@@ -858,8 +922,8 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
lastargc = argc;
if (!strncmp(argv[argc - 1], "filter=", 7) && !filter) {
filter = xstrdup(argv[--argc] + 7);
- } else if (!strncmp(argv[argc - 1], "type=", 5) && !type) {
- type = xstrdup(argv[--argc] + 5);
+ } else if (!strncmp(argv[argc - 1], "type=", 5) && !types_list) {
+ types_list = xstrdup(argv[--argc] + 5);
}
}
@@ -892,19 +956,12 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
}
}
- if (type) {
- error = EINVAL;
- for (int i = 0; i < ARRAY_SIZE(supported_dump_types); i++) {
- if (!strcmp(supported_dump_types[i], type)) {
- error = 0;
- break;
- }
- }
- if (error) {
- dpctl_error(dpctl_p, error, "Failed to parse type (%s)", type);
- goto out_free;
- }
+ memset(&dump_types, 0, sizeof dump_types);
+ error = populate_dump_types(types_list, &dump_types, dpctl_p);
+ if (error) {
+ goto out_free;
}
+ determine_dpif_flow_dump_types(&dump_types, &dpif_dump_types);
/* Make sure that these values are different. PMD_ID_NULL means that the
* pmd is unspecified (e.g. because the datapath doesn't have different
@@ -914,7 +971,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
ds_init(&ds);
memset(&f, 0, sizeof f);
- flow_dump = dpif_flow_dump_create(dpif, false, (type ? type : "dpctl"));
+ flow_dump = dpif_flow_dump_create(dpif, false, &dpif_dump_types);
flow_dump_thread = dpif_flow_dump_thread_create(flow_dump);
while (dpif_flow_dump_next(flow_dump_thread, &f, 1)) {
if (filter) {
@@ -950,7 +1007,7 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
}
pmd_id = f.pmd_id;
}
- if (!type || flow_passes_type_filter(&f, type)) {
+ if (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));
}
@@ -968,7 +1025,7 @@ out_dpifclose:
dpif_close(dpif);
out_free:
free(filter);
- free(type);
+ free(types_list);
return error;
}