X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=rdma%2Futils.c;h=11ed8a73b2d3e4ea62a20927464bd1af8e45f920;hb=f99ea67684c6063e750912846aae4066e01a55e6;hp=c7023367001eff091050b4bbef1dc5ba63d75689;hpb=f0cabaca38e5fafb455373e2d2747afecc7299fd;p=mirror_iproute2.git diff --git a/rdma/utils.c b/rdma/utils.c index c7023367..11ed8a73 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -1,11 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* * utils.c RDMA tool - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * * Authors: Leon Romanovsky */ @@ -18,14 +13,14 @@ int rd_argc(struct rd *rd) return rd->argc; } -static char *rd_argv(struct rd *rd) +char *rd_argv(struct rd *rd) { if (!rd_argc(rd)) return NULL; return *rd->argv; } -static int strcmpx(const char *str1, const char *str2) +int strcmpx(const char *str1, const char *str2) { if (strlen(str1) > strlen(str2)) return -1; @@ -39,7 +34,7 @@ static bool rd_argv_match(struct rd *rd, const char *pattern) return strcmpx(rd_argv(rd), pattern) == 0; } -static void rd_arg_inc(struct rd *rd) +void rd_arg_inc(struct rd *rd) { if (!rd_argc(rd)) return; @@ -47,7 +42,7 @@ static void rd_arg_inc(struct rd *rd) rd->argv++; } -static bool rd_no_arg(struct rd *rd) +bool rd_no_arg(struct rd *rd) { return rd_argc(rd) == 0; } @@ -126,6 +121,7 @@ static int add_filter(struct rd *rd, char *key, char *value, struct filter_entry *fe; bool key_found = false; int idx = 0; + char *endp; int ret; fe = calloc(1, sizeof(*fe)); @@ -168,6 +164,11 @@ static int add_filter(struct rd *rd, char *key, char *value, goto err_alloc; } + errno = 0; + strtol(fe->value, &endp, 10); + if (valid_filters[idx].is_doit && !errno && *endp == '\0') + fe->is_doit = true; + for (idx = 0; idx < strlen(fe->value); idx++) fe->value[idx] = tolower(fe->value[idx]); @@ -182,6 +183,20 @@ err: return ret; } +bool rd_doit_index(struct rd *rd, uint32_t *idx) +{ + struct filter_entry *fe; + + list_for_each_entry(fe, &rd->filter_list, list) { + if (fe->is_doit) { + *idx = atoi(fe->value); + return true; + } + } + + return false; +} + int rd_build_filter(struct rd *rd, const struct filters valid_filters[]) { int ret = 0; @@ -218,7 +233,7 @@ out: return ret; } -bool rd_check_is_key_exist(struct rd *rd, const char *key) +static bool rd_check_is_key_exist(struct rd *rd, const char *key) { struct filter_entry *fe; @@ -234,8 +249,8 @@ bool rd_check_is_key_exist(struct rd *rd, const char *key) * Check if string entry is filtered: * * key doesn't exist -> user didn't request -> not filtered */ -bool rd_check_is_string_filtered(struct rd *rd, - const char *key, const char *val) +static bool rd_check_is_string_filtered(struct rd *rd, const char *key, + const char *val) { bool key_is_filtered = false; struct filter_entry *fe; @@ -285,7 +300,7 @@ out: * Check if key is filtered: * key doesn't exist -> user didn't request -> not filtered */ -bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val) +static bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val) { bool key_is_filtered = false; struct filter_entry *fe; @@ -334,6 +349,24 @@ out: return key_is_filtered; } +bool rd_is_filtered_attr(struct rd *rd, const char *key, uint32_t val, + struct nlattr *attr) +{ + if (!attr) + return rd_check_is_key_exist(rd, key); + + return rd_check_is_filtered(rd, key, val); +} + +bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val, + struct nlattr *attr) +{ + if (!attr) + rd_check_is_key_exist(rd, key); + + return rd_check_is_string_filtered(rd, key, val); +} + static void filters_cleanup(struct rd *rd) { struct filter_entry *fe, *tmp; @@ -404,7 +437,7 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_DRIVER_U64] = MNL_TYPE_U64, }; -static int rd_attr_check(const struct nlattr *attr, int *typep) +int rd_attr_check(const struct nlattr *attr, int *typep) { int type; @@ -577,6 +610,16 @@ out: return ret; } +int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd)) +{ + if (rd_no_arg(rd)) { + pr_err("Please provide device name.\n"); + return -EINVAL; + } + + return rd_exec_dev(rd, cb); +} + int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str) { const struct rd_cmd *c; @@ -650,10 +693,28 @@ int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq) ret = mnl_cb_run(buf, ret, seq, portid, callback, data); } while (ret > 0); + if (ret < 0 && !rd->suppress_errors) + perror("error"); + mnl_socket_close(rd->nl); return ret; } +static int null_cb(const struct nlmsghdr *nlh, void *data) +{ + return MNL_CB_OK; +} + +int rd_sendrecv_msg(struct rd *rd, unsigned int seq) +{ + int ret; + + ret = rd_send_msg(rd); + if (!ret) + ret = rd_recv_msg(rd, null_cb, rd, seq); + return ret; +} + static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name) { struct dev_map *dev_map; @@ -696,7 +757,7 @@ void newline(struct rd *rd) pr_out("\n"); } -static void newline_indent(struct rd *rd) +void newline_indent(struct rd *rd) { newline(rd); if (!rd->json_output) @@ -786,27 +847,37 @@ static int print_driver_entry(struct rd *rd, struct nlattr *key_attr, struct nlattr *val_attr, enum rdma_nldev_print_type print_type) { - const char *key_str = mnl_attr_get_str(key_attr); int attr_type = nla_type(val_attr); + int ret = -EINVAL; + char *key_str; + + if (asprintf(&key_str, "drv_%s", mnl_attr_get_str(key_attr)) == -1) + return -ENOMEM; switch (attr_type) { case RDMA_NLDEV_ATTR_DRIVER_STRING: - return print_driver_string(rd, key_str, - mnl_attr_get_str(val_attr)); + ret = print_driver_string(rd, key_str, + mnl_attr_get_str(val_attr)); + break; case RDMA_NLDEV_ATTR_DRIVER_S32: - return print_driver_s32(rd, key_str, - mnl_attr_get_u32(val_attr), print_type); + ret = print_driver_s32(rd, key_str, mnl_attr_get_u32(val_attr), + print_type); + break; case RDMA_NLDEV_ATTR_DRIVER_U32: - return print_driver_u32(rd, key_str, - mnl_attr_get_u32(val_attr), print_type); + ret = print_driver_u32(rd, key_str, mnl_attr_get_u32(val_attr), + print_type); + break; case RDMA_NLDEV_ATTR_DRIVER_S64: - return print_driver_s64(rd, key_str, - mnl_attr_get_u64(val_attr), print_type); + ret = print_driver_s64(rd, key_str, mnl_attr_get_u64(val_attr), + print_type); + break; case RDMA_NLDEV_ATTR_DRIVER_U64: - return print_driver_u64(rd, key_str, - mnl_attr_get_u64(val_attr), print_type); + ret = print_driver_u64(rd, key_str, mnl_attr_get_u64(val_attr), + print_type); + break; } - return -EINVAL; + free(key_str); + return ret; } void print_driver_table(struct rd *rd, struct nlattr *tb)