}
}
-static void pr_out_dpipe_action(struct dpipe_ctx *ctx,
- uint32_t header_id, uint32_t field_id,
- uint32_t action_type, bool global)
+struct dpipe_op_info {
+ uint32_t header_id;
+ uint32_t field_id;
+ bool header_global;
+};
+
+struct dpipe_action {
+ struct dpipe_op_info info;
+ uint32_t type;
+};
+
+static void pr_out_dpipe_action(struct dpipe_action *action,
+ struct dpipe_ctx *ctx)
{
+ struct dpipe_op_info *op_info = &action->info;
const char *mapping;
- pr_out_str(ctx->dl, "type", dpipe_action_type_e2s(action_type));
- pr_out_str(ctx->dl, "header", dpipe_header_id2s(ctx, header_id,
- global));
- pr_out_str(ctx->dl, "field", dpipe_field_id2s(ctx, header_id, field_id,
- global));
- mapping = dpipe_mapping_get(ctx, header_id, field_id, global);
+ pr_out_str(ctx->dl, "type",
+ dpipe_action_type_e2s(action->type));
+ pr_out_str(ctx->dl, "header",
+ dpipe_header_id2s(ctx, op_info->header_id,
+ op_info->header_global));
+ pr_out_str(ctx->dl, "field",
+ dpipe_field_id2s(ctx, op_info->header_id,
+ op_info->field_id,
+ op_info->header_global));
+ mapping = dpipe_mapping_get(ctx, op_info->header_id,
+ op_info->field_id,
+ op_info->header_global);
if (mapping)
pr_out_str(ctx->dl, "mapping", mapping);
}
-static int dpipe_action_show(struct dpipe_ctx *ctx, struct nlattr *nl)
+static int dpipe_action_parse(struct dpipe_action *action, struct nlattr *nl)
{
struct nlattr *nla_action[DEVLINK_ATTR_MAX + 1] = {};
- uint32_t header_id, field_id, action_type;
- bool global;
int err;
err = mnl_attr_parse_nested(nl, attr_cb, nla_action);
return -EINVAL;
}
- header_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID]);
- field_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]);
- action_type = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE]);
- global = !!mnl_attr_get_u8(nla_action[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
+ action->type = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE]);
+ action->info.header_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID]);
+ action->info.field_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]);
+ action->info.header_global = !!mnl_attr_get_u8(nla_action[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
- pr_out_dpipe_action(ctx, header_id, field_id, action_type, global);
return 0;
}
struct nlattr *nla_actions)
{
struct nlattr *nla_action;
+ struct dpipe_action action;
mnl_attr_for_each_nested(nla_action, nla_actions) {
pr_out_entry_start(ctx->dl);
- if (dpipe_action_show(ctx, nla_action))
- goto err_action_show;
+ if (dpipe_action_parse(&action, nla_action))
+ goto err_action_parse;
+ pr_out_dpipe_action(&action, ctx);
pr_out_entry_end(ctx->dl);
}
return 0;
-err_action_show:
+err_action_parse:
pr_out_entry_end(ctx->dl);
return -EINVAL;
}
}
}
-static void pr_out_dpipe_match(struct dpipe_ctx *ctx,
- uint32_t header_id, uint32_t field_id,
- uint32_t match_type, bool global)
+struct dpipe_match {
+ struct dpipe_op_info info;
+ uint32_t type;
+};
+
+static void pr_out_dpipe_match(struct dpipe_match *match,
+ struct dpipe_ctx *ctx)
{
+ struct dpipe_op_info *op_info = &match->info;
const char *mapping;
- pr_out_str(ctx->dl, "type", dpipe_match_type_e2s(match_type));
- pr_out_str(ctx->dl, "header", dpipe_header_id2s(ctx, header_id,
- global));
- pr_out_str(ctx->dl, "field", dpipe_field_id2s(ctx, header_id, field_id,
- global));
- mapping = dpipe_mapping_get(ctx, header_id, field_id, global);
+ pr_out_str(ctx->dl, "type",
+ dpipe_match_type_e2s(match->type));
+ pr_out_str(ctx->dl, "header",
+ dpipe_header_id2s(ctx, op_info->header_id,
+ op_info->header_global));
+ pr_out_str(ctx->dl, "field",
+ dpipe_field_id2s(ctx, op_info->header_id,
+ op_info->field_id,
+ op_info->header_global));
+ mapping = dpipe_mapping_get(ctx, op_info->header_id,
+ op_info->field_id,
+ op_info->header_global);
if (mapping)
pr_out_str(ctx->dl, "mapping", mapping);
-
}
-static int dpipe_match_show(struct dpipe_ctx *ctx, struct nlattr *nl)
+static int dpipe_match_parse(struct dpipe_match *match,
+ struct nlattr *nl)
+
{
struct nlattr *nla_match[DEVLINK_ATTR_MAX + 1] = {};
- uint32_t header_id, field_id, match_type;
- bool global;
int err;
err = mnl_attr_parse_nested(nl, attr_cb, nla_match);
return -EINVAL;
}
- match_type = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE]);
- header_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID]);
- field_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]);
- global = !!mnl_attr_get_u8(nla_match[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
+ match->type = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE]);
+ match->info.header_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID]);
+ match->info.field_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]);
+ match->info.header_global = !!mnl_attr_get_u8(nla_match[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
- pr_out_dpipe_match(ctx, header_id, field_id, match_type, global);
return 0;
}
struct nlattr *nla_matches)
{
struct nlattr *nla_match;
+ struct dpipe_match match;
mnl_attr_for_each_nested(nla_match, nla_matches) {
pr_out_entry_start(ctx->dl);
- if (dpipe_match_show(ctx, nla_match))
- goto err_match_show;
+ if (dpipe_match_parse(&match, nla_match))
+ goto err_match_parse;
+ pr_out_dpipe_match(&match, ctx);
pr_out_entry_end(ctx->dl);
}
return 0;
-err_match_show:
+err_match_parse:
pr_out_entry_end(ctx->dl);
return -EINVAL;
}
return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
}
-static int dpipe_entry_value_show(struct dpipe_ctx *ctx,
- struct nlattr **nla_match_value)
+enum dpipe_value_type {
+ DPIPE_VALUE_TYPE_VALUE,
+ DPIPE_VALUE_TYPE_MASK,
+};
+
+static const char *
+dpipe_value_type_e2s(enum dpipe_value_type type)
{
+ switch (type) {
+ case DPIPE_VALUE_TYPE_VALUE:
+ return "value";
+ case DPIPE_VALUE_TYPE_MASK:
+ return "value_mask";
+ default:
+ return "<unknown>";
+ }
+}
+
+struct dpipe_field_printer {
+ unsigned int field_id;
+ void (*printer)(struct dpipe_ctx *, enum dpipe_value_type, void *);
+};
+
+struct dpipe_header_printer {
+ struct dpipe_field_printer *printers;
+ unsigned int printers_count;
+ unsigned int header_id;
+};
+
+static struct dpipe_header_printer *dpipe_header_printers[] = {};
+
+static int dpipe_print_prot_header(struct dpipe_ctx *ctx,
+ struct dpipe_op_info *info,
+ enum dpipe_value_type type,
+ void *value)
+{
+ unsigned int header_printers_count = ARRAY_SIZE(dpipe_header_printers);
+ struct dpipe_header_printer *header_printer;
+ struct dpipe_field_printer *field_printer;
+ unsigned int field_printers_count;
+ int j;
+ int i;
+
+ for (i = 0; i < header_printers_count; i++) {
+ header_printer = dpipe_header_printers[i];
+ if (header_printer->header_id != info->header_id)
+ continue;
+ field_printers_count = header_printer->printers_count;
+ for (j = 0; j < field_printers_count; j++) {
+ field_printer = &header_printer->printers[j];
+ if (field_printer->field_id != info->field_id)
+ continue;
+ field_printer->printer(ctx, type, value);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static void __pr_out_entry_value(struct dpipe_ctx *ctx,
+ void *value,
+ unsigned int value_len,
+ struct dpipe_op_info *info,
+ enum dpipe_value_type type)
+{
+ if (info->header_global &&
+ !dpipe_print_prot_header(ctx, info, type, value))
+ return;
+
+ if (value_len == sizeof(uint32_t)) {
+ uint32_t *value_32 = value;
+
+ pr_out_uint(ctx->dl, dpipe_value_type_e2s(type), *value_32);
+ }
+}
+
+static void pr_out_dpipe_entry_value(struct dpipe_ctx *ctx,
+ struct nlattr **nla_match_value,
+ struct dpipe_op_info *info)
+{
+ void *value, *value_mask;
+ uint32_t value_mapping;
uint16_t value_len;
bool mask, mapping;
mapping = !!nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING];
value_len = mnl_attr_get_payload_len(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
- if (value_len == sizeof(uint32_t)) {
- uint32_t value, value_mask, value_mapping;
-
- if (mapping) {
- value_mapping = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING]);
- pr_out_uint(ctx->dl, "mapping_value", value_mapping);
- }
+ value = mnl_attr_get_payload(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
- if (mask) {
- value_mask = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MASK]);
- pr_out_uint(ctx->dl, "mask_value", value_mask);
- }
-
- value = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
- pr_out_uint(ctx->dl, "value", value);
+ if (mapping) {
+ value_mapping = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING]);
+ pr_out_uint(ctx->dl, "mapping_value", value_mapping);
+ }
- } else {
- return -EINVAL;
+ if (mask) {
+ value_mask = mnl_attr_get_payload(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
+ __pr_out_entry_value(ctx, value_mask, value_len, info,
+ DPIPE_VALUE_TYPE_MASK);
}
- return 0;
+ __pr_out_entry_value(ctx, value, value_len, info, DPIPE_VALUE_TYPE_VALUE);
}
static int dpipe_entry_match_value_show(struct dpipe_ctx *ctx,
struct nlattr *nl)
{
struct nlattr *nla_match_value[DEVLINK_ATTR_MAX + 1] = {};
+ struct dpipe_match match;
int err;
err = mnl_attr_parse_nested(nl, attr_cb, nla_match_value);
}
pr_out_entry_start(ctx->dl);
- if (dpipe_match_show(ctx, nla_match_value[DEVLINK_ATTR_DPIPE_MATCH]))
- goto err_match_show;
- if (dpipe_entry_value_show(ctx, nla_match_value))
- goto err_value_show;
+ if (dpipe_match_parse(&match,
+ nla_match_value[DEVLINK_ATTR_DPIPE_MATCH]))
+ goto err_match_parse;
+ pr_out_dpipe_match(&match, ctx);
+ pr_out_dpipe_entry_value(ctx, nla_match_value, &match.info);
pr_out_entry_end(ctx->dl);
return 0;
-err_match_show:
-err_value_show:
+err_match_parse:
pr_out_entry_end(ctx->dl);
return -EINVAL;
}
struct nlattr *nl)
{
struct nlattr *nla_action_value[DEVLINK_ATTR_MAX + 1] = {};
+ struct dpipe_action action;
int err;
err = mnl_attr_parse_nested(nl, attr_cb, nla_action_value);
}
pr_out_entry_start(ctx->dl);
- if (dpipe_action_show(ctx, nla_action_value[DEVLINK_ATTR_DPIPE_ACTION]))
- goto err_action_show;
- if (dpipe_entry_value_show(ctx, nla_action_value))
- goto err_value_show;
+ if (dpipe_action_parse(&action,
+ nla_action_value[DEVLINK_ATTR_DPIPE_ACTION]))
+ goto err_action_parse;
+ pr_out_dpipe_action(&action, ctx);
+ pr_out_dpipe_entry_value(ctx, nla_action_value, &action.info);
pr_out_entry_end(ctx->dl);
return 0;
-err_action_show:
-err_value_show:
+err_action_parse:
pr_out_entry_end(ctx->dl);
return -EINVAL;
}