|
@@ -81,19 +81,19 @@ static unsigned int get_possible_cpus(void)
|
|
|
|
|
|
fd = open("/sys/devices/system/cpu/possible", O_RDONLY);
|
|
fd = open("/sys/devices/system/cpu/possible", O_RDONLY);
|
|
if (fd < 0) {
|
|
if (fd < 0) {
|
|
- err("can't open sysfs possible cpus\n");
|
|
|
|
|
|
+ p_err("can't open sysfs possible cpus");
|
|
exit(-1);
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
|
|
n = read(fd, buf, sizeof(buf));
|
|
n = read(fd, buf, sizeof(buf));
|
|
if (n < 2) {
|
|
if (n < 2) {
|
|
- err("can't read sysfs possible cpus\n");
|
|
|
|
|
|
+ p_err("can't read sysfs possible cpus");
|
|
exit(-1);
|
|
exit(-1);
|
|
}
|
|
}
|
|
close(fd);
|
|
close(fd);
|
|
|
|
|
|
if (n == sizeof(buf)) {
|
|
if (n == sizeof(buf)) {
|
|
- err("read sysfs possible cpus overflow\n");
|
|
|
|
|
|
+ p_err("read sysfs possible cpus overflow");
|
|
exit(-1);
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -161,14 +161,14 @@ static int map_parse_fd(int *argc, char ***argv)
|
|
|
|
|
|
id = strtoul(**argv, &endptr, 0);
|
|
id = strtoul(**argv, &endptr, 0);
|
|
if (*endptr) {
|
|
if (*endptr) {
|
|
- err("can't parse %s as ID\n", **argv);
|
|
|
|
|
|
+ p_err("can't parse %s as ID", **argv);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
NEXT_ARGP();
|
|
NEXT_ARGP();
|
|
|
|
|
|
fd = bpf_map_get_fd_by_id(id);
|
|
fd = bpf_map_get_fd_by_id(id);
|
|
if (fd < 0)
|
|
if (fd < 0)
|
|
- err("get map by id (%u): %s\n", id, strerror(errno));
|
|
|
|
|
|
+ p_err("get map by id (%u): %s", id, strerror(errno));
|
|
return fd;
|
|
return fd;
|
|
} else if (is_prefix(**argv, "pinned")) {
|
|
} else if (is_prefix(**argv, "pinned")) {
|
|
char *path;
|
|
char *path;
|
|
@@ -181,7 +181,7 @@ static int map_parse_fd(int *argc, char ***argv)
|
|
return open_obj_pinned_any(path, BPF_OBJ_MAP);
|
|
return open_obj_pinned_any(path, BPF_OBJ_MAP);
|
|
}
|
|
}
|
|
|
|
|
|
- err("expected 'id' or 'pinned', got: '%s'?\n", **argv);
|
|
|
|
|
|
+ p_err("expected 'id' or 'pinned', got: '%s'?", **argv);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -197,7 +197,7 @@ map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, info, info_len);
|
|
err = bpf_obj_get_info_by_fd(fd, info, info_len);
|
|
if (err) {
|
|
if (err) {
|
|
- err("can't get map info: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("can't get map info: %s", strerror(errno));
|
|
close(fd);
|
|
close(fd);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
@@ -205,8 +205,45 @@ map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
|
|
return fd;
|
|
return fd;
|
|
}
|
|
}
|
|
|
|
|
|
-static void print_entry(struct bpf_map_info *info, unsigned char *key,
|
|
|
|
- unsigned char *value)
|
|
|
|
|
|
+static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
|
|
|
|
+ unsigned char *value)
|
|
|
|
+{
|
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
|
+
|
|
|
|
+ if (!map_is_per_cpu(info->type)) {
|
|
|
|
+ jsonw_name(json_wtr, "key");
|
|
|
|
+ print_hex_data_json(key, info->key_size);
|
|
|
|
+ jsonw_name(json_wtr, "value");
|
|
|
|
+ print_hex_data_json(value, info->value_size);
|
|
|
|
+ } else {
|
|
|
|
+ unsigned int i, n;
|
|
|
|
+
|
|
|
|
+ n = get_possible_cpus();
|
|
|
|
+
|
|
|
|
+ jsonw_name(json_wtr, "key");
|
|
|
|
+ print_hex_data_json(key, info->key_size);
|
|
|
|
+
|
|
|
|
+ jsonw_name(json_wtr, "values");
|
|
|
|
+ jsonw_start_array(json_wtr);
|
|
|
|
+ for (i = 0; i < n; i++) {
|
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
|
+
|
|
|
|
+ jsonw_int_field(json_wtr, "cpu", i);
|
|
|
|
+
|
|
|
|
+ jsonw_name(json_wtr, "value");
|
|
|
|
+ print_hex_data_json(value + i * info->value_size,
|
|
|
|
+ info->value_size);
|
|
|
|
+
|
|
|
|
+ jsonw_end_object(json_wtr);
|
|
|
|
+ }
|
|
|
|
+ jsonw_end_array(json_wtr);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ jsonw_end_object(json_wtr);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void print_entry_plain(struct bpf_map_info *info, unsigned char *key,
|
|
|
|
+ unsigned char *value)
|
|
{
|
|
{
|
|
if (!map_is_per_cpu(info->type)) {
|
|
if (!map_is_per_cpu(info->type)) {
|
|
bool single_line, break_names;
|
|
bool single_line, break_names;
|
|
@@ -251,14 +288,14 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val,
|
|
while (i < n && argv[i]) {
|
|
while (i < n && argv[i]) {
|
|
val[i] = strtoul(argv[i], &endptr, 0);
|
|
val[i] = strtoul(argv[i], &endptr, 0);
|
|
if (*endptr) {
|
|
if (*endptr) {
|
|
- err("error parsing byte: %s\n", argv[i]);
|
|
|
|
|
|
+ p_err("error parsing byte: %s", argv[i]);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
i++;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
|
|
if (i != n) {
|
|
if (i != n) {
|
|
- err("%s expected %d bytes got %d\n", name, n, i);
|
|
|
|
|
|
+ p_err("%s expected %d bytes got %d", name, n, i);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -272,16 +309,16 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
if (!*argv) {
|
|
if (!*argv) {
|
|
if (!key && !value)
|
|
if (!key && !value)
|
|
return 0;
|
|
return 0;
|
|
- err("did not find %s\n", key ? "key" : "value");
|
|
|
|
|
|
+ p_err("did not find %s", key ? "key" : "value");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
if (is_prefix(*argv, "key")) {
|
|
if (is_prefix(*argv, "key")) {
|
|
if (!key) {
|
|
if (!key) {
|
|
if (key_size)
|
|
if (key_size)
|
|
- err("duplicate key\n");
|
|
|
|
|
|
+ p_err("duplicate key");
|
|
else
|
|
else
|
|
- err("unnecessary key\n");
|
|
|
|
|
|
+ p_err("unnecessary key");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -296,9 +333,9 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
|
|
|
|
if (!value) {
|
|
if (!value) {
|
|
if (value_size)
|
|
if (value_size)
|
|
- err("duplicate value\n");
|
|
|
|
|
|
+ p_err("duplicate value");
|
|
else
|
|
else
|
|
- err("unnecessary value\n");
|
|
|
|
|
|
+ p_err("unnecessary value");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -308,11 +345,11 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
int argc = 2;
|
|
int argc = 2;
|
|
|
|
|
|
if (value_size != 4) {
|
|
if (value_size != 4) {
|
|
- err("value smaller than 4B for map in map?\n");
|
|
|
|
|
|
+ p_err("value smaller than 4B for map in map?");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
if (!argv[0] || !argv[1]) {
|
|
if (!argv[0] || !argv[1]) {
|
|
- err("not enough value arguments for map in map\n");
|
|
|
|
|
|
+ p_err("not enough value arguments for map in map");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -326,11 +363,11 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
int argc = 2;
|
|
int argc = 2;
|
|
|
|
|
|
if (value_size != 4) {
|
|
if (value_size != 4) {
|
|
- err("value smaller than 4B for map of progs?\n");
|
|
|
|
|
|
+ p_err("value smaller than 4B for map of progs?");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
if (!argv[0] || !argv[1]) {
|
|
if (!argv[0] || !argv[1]) {
|
|
- err("not enough value arguments for map of progs\n");
|
|
|
|
|
|
+ p_err("not enough value arguments for map of progs");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -351,7 +388,7 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
} else if (is_prefix(*argv, "any") || is_prefix(*argv, "noexist") ||
|
|
} else if (is_prefix(*argv, "any") || is_prefix(*argv, "noexist") ||
|
|
is_prefix(*argv, "exist")) {
|
|
is_prefix(*argv, "exist")) {
|
|
if (!flags) {
|
|
if (!flags) {
|
|
- err("flags specified multiple times: %s\n", *argv);
|
|
|
|
|
|
+ p_err("flags specified multiple times: %s", *argv);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -366,11 +403,45 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|
value_size, NULL, value_fd);
|
|
value_size, NULL, value_fd);
|
|
}
|
|
}
|
|
|
|
|
|
- err("expected key or value, got: %s\n", *argv);
|
|
|
|
|
|
+ p_err("expected key or value, got: %s", *argv);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
-static int show_map_close(int fd, struct bpf_map_info *info)
|
|
|
|
|
|
+static int show_map_close_json(int fd, struct bpf_map_info *info)
|
|
|
|
+{
|
|
|
|
+ char *memlock;
|
|
|
|
+
|
|
|
|
+ memlock = get_fdinfo(fd, "memlock");
|
|
|
|
+ close(fd);
|
|
|
|
+
|
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
|
+
|
|
|
|
+ jsonw_uint_field(json_wtr, "id", info->id);
|
|
|
|
+ if (info->type < ARRAY_SIZE(map_type_name))
|
|
|
|
+ jsonw_string_field(json_wtr, "type",
|
|
|
|
+ map_type_name[info->type]);
|
|
|
|
+ else
|
|
|
|
+ jsonw_uint_field(json_wtr, "type", info->type);
|
|
|
|
+
|
|
|
|
+ if (*info->name)
|
|
|
|
+ jsonw_string_field(json_wtr, "name", info->name);
|
|
|
|
+
|
|
|
|
+ jsonw_name(json_wtr, "flags");
|
|
|
|
+ jsonw_printf(json_wtr, "%#x", info->map_flags);
|
|
|
|
+ jsonw_uint_field(json_wtr, "bytes_key", info->key_size);
|
|
|
|
+ jsonw_uint_field(json_wtr, "bytes_value", info->value_size);
|
|
|
|
+ jsonw_uint_field(json_wtr, "max_entries", info->max_entries);
|
|
|
|
+
|
|
|
|
+ if (memlock)
|
|
|
|
+ jsonw_int_field(json_wtr, "bytes_memlock", atoi(memlock));
|
|
|
|
+ free(memlock);
|
|
|
|
+
|
|
|
|
+ jsonw_end_object(json_wtr);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int show_map_close_plain(int fd, struct bpf_map_info *info)
|
|
{
|
|
{
|
|
char *memlock;
|
|
char *memlock;
|
|
|
|
|
|
@@ -412,39 +483,48 @@ static int do_show(int argc, char **argv)
|
|
if (fd < 0)
|
|
if (fd < 0)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
- return show_map_close(fd, &info);
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ return show_map_close_json(fd, &info);
|
|
|
|
+ else
|
|
|
|
+ return show_map_close_plain(fd, &info);
|
|
}
|
|
}
|
|
|
|
|
|
if (argc)
|
|
if (argc)
|
|
return BAD_ARG();
|
|
return BAD_ARG();
|
|
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_start_array(json_wtr);
|
|
while (true) {
|
|
while (true) {
|
|
err = bpf_map_get_next_id(id, &id);
|
|
err = bpf_map_get_next_id(id, &id);
|
|
if (err) {
|
|
if (err) {
|
|
if (errno == ENOENT)
|
|
if (errno == ENOENT)
|
|
break;
|
|
break;
|
|
- err("can't get next map: %s\n", strerror(errno));
|
|
|
|
- if (errno == EINVAL)
|
|
|
|
- err("kernel too old?\n");
|
|
|
|
|
|
+ p_err("can't get next map: %s%s", strerror(errno),
|
|
|
|
+ errno == EINVAL ? " -- kernel too old?" : "");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
fd = bpf_map_get_fd_by_id(id);
|
|
fd = bpf_map_get_fd_by_id(id);
|
|
if (fd < 0) {
|
|
if (fd < 0) {
|
|
- err("can't get map by id (%u): %s\n",
|
|
|
|
- id, strerror(errno));
|
|
|
|
|
|
+ p_err("can't get map by id (%u): %s",
|
|
|
|
+ id, strerror(errno));
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
if (err) {
|
|
if (err) {
|
|
- err("can't get map info: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("can't get map info: %s", strerror(errno));
|
|
close(fd);
|
|
close(fd);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
- show_map_close(fd, &info);
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ show_map_close_json(fd, &info);
|
|
|
|
+ else
|
|
|
|
+ show_map_close_plain(fd, &info);
|
|
}
|
|
}
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_end_array(json_wtr);
|
|
|
|
|
|
return errno == ENOENT ? 0 : -1;
|
|
return errno == ENOENT ? 0 : -1;
|
|
}
|
|
}
|
|
@@ -466,7 +546,7 @@ static int do_dump(int argc, char **argv)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
if (map_is_map_of_maps(info.type) || map_is_map_of_progs(info.type)) {
|
|
if (map_is_map_of_maps(info.type) || map_is_map_of_progs(info.type)) {
|
|
- err("Dumping maps of maps and program maps not supported\n");
|
|
|
|
|
|
+ p_err("Dumping maps of maps and program maps not supported");
|
|
close(fd);
|
|
close(fd);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -474,12 +554,14 @@ static int do_dump(int argc, char **argv)
|
|
key = malloc(info.key_size);
|
|
key = malloc(info.key_size);
|
|
value = alloc_value(&info);
|
|
value = alloc_value(&info);
|
|
if (!key || !value) {
|
|
if (!key || !value) {
|
|
- err("mem alloc failed\n");
|
|
|
|
|
|
+ p_err("mem alloc failed");
|
|
err = -1;
|
|
err = -1;
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
|
|
|
|
prev_key = NULL;
|
|
prev_key = NULL;
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_start_array(json_wtr);
|
|
while (true) {
|
|
while (true) {
|
|
err = bpf_map_get_next_key(fd, prev_key, key);
|
|
err = bpf_map_get_next_key(fd, prev_key, key);
|
|
if (err) {
|
|
if (err) {
|
|
@@ -489,18 +571,35 @@ static int do_dump(int argc, char **argv)
|
|
}
|
|
}
|
|
|
|
|
|
if (!bpf_map_lookup_elem(fd, key, value)) {
|
|
if (!bpf_map_lookup_elem(fd, key, value)) {
|
|
- print_entry(&info, key, value);
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ print_entry_json(&info, key, value);
|
|
|
|
+ else
|
|
|
|
+ print_entry_plain(&info, key, value);
|
|
} else {
|
|
} else {
|
|
- info("can't lookup element with key: ");
|
|
|
|
- fprint_hex(stderr, key, info.key_size, " ");
|
|
|
|
- fprintf(stderr, "\n");
|
|
|
|
|
|
+ if (json_output) {
|
|
|
|
+ jsonw_name(json_wtr, "key");
|
|
|
|
+ print_hex_data_json(key, info.key_size);
|
|
|
|
+ jsonw_name(json_wtr, "value");
|
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
|
+ jsonw_string_field(json_wtr, "error",
|
|
|
|
+ "can't lookup element");
|
|
|
|
+ jsonw_end_object(json_wtr);
|
|
|
|
+ } else {
|
|
|
|
+ p_info("can't lookup element with key: ");
|
|
|
|
+ fprint_hex(stderr, key, info.key_size, " ");
|
|
|
|
+ fprintf(stderr, "\n");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
prev_key = key;
|
|
prev_key = key;
|
|
num_elems++;
|
|
num_elems++;
|
|
}
|
|
}
|
|
|
|
|
|
- printf("Found %u element%s\n", num_elems, num_elems != 1 ? "s" : "");
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ jsonw_end_array(json_wtr);
|
|
|
|
+ else
|
|
|
|
+ printf("Found %u element%s\n", num_elems,
|
|
|
|
+ num_elems != 1 ? "s" : "");
|
|
|
|
|
|
exit_free:
|
|
exit_free:
|
|
free(key);
|
|
free(key);
|
|
@@ -529,7 +628,7 @@ static int do_update(int argc, char **argv)
|
|
key = malloc(info.key_size);
|
|
key = malloc(info.key_size);
|
|
value = alloc_value(&info);
|
|
value = alloc_value(&info);
|
|
if (!key || !value) {
|
|
if (!key || !value) {
|
|
- err("mem alloc failed");
|
|
|
|
|
|
+ p_err("mem alloc failed");
|
|
err = -1;
|
|
err = -1;
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
@@ -541,7 +640,7 @@ static int do_update(int argc, char **argv)
|
|
|
|
|
|
err = bpf_map_update_elem(fd, key, value, flags);
|
|
err = bpf_map_update_elem(fd, key, value, flags);
|
|
if (err) {
|
|
if (err) {
|
|
- err("update failed: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("update failed: %s", strerror(errno));
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -552,6 +651,8 @@ exit_free:
|
|
free(value);
|
|
free(value);
|
|
close(fd);
|
|
close(fd);
|
|
|
|
|
|
|
|
+ if (!err && json_output)
|
|
|
|
+ jsonw_null(json_wtr);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -573,7 +674,7 @@ static int do_lookup(int argc, char **argv)
|
|
key = malloc(info.key_size);
|
|
key = malloc(info.key_size);
|
|
value = alloc_value(&info);
|
|
value = alloc_value(&info);
|
|
if (!key || !value) {
|
|
if (!key || !value) {
|
|
- err("mem alloc failed");
|
|
|
|
|
|
+ p_err("mem alloc failed");
|
|
err = -1;
|
|
err = -1;
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
@@ -584,13 +685,20 @@ static int do_lookup(int argc, char **argv)
|
|
|
|
|
|
err = bpf_map_lookup_elem(fd, key, value);
|
|
err = bpf_map_lookup_elem(fd, key, value);
|
|
if (!err) {
|
|
if (!err) {
|
|
- print_entry(&info, key, value);
|
|
|
|
|
|
+ if (json_output)
|
|
|
|
+ print_entry_json(&info, key, value);
|
|
|
|
+ else
|
|
|
|
+ print_entry_plain(&info, key, value);
|
|
} else if (errno == ENOENT) {
|
|
} else if (errno == ENOENT) {
|
|
- printf("key:\n");
|
|
|
|
- fprint_hex(stdout, key, info.key_size, " ");
|
|
|
|
- printf("\n\nNot found\n");
|
|
|
|
|
|
+ if (json_output) {
|
|
|
|
+ jsonw_null(json_wtr);
|
|
|
|
+ } else {
|
|
|
|
+ printf("key:\n");
|
|
|
|
+ fprint_hex(stdout, key, info.key_size, " ");
|
|
|
|
+ printf("\n\nNot found\n");
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- err("lookup failed: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("lookup failed: %s", strerror(errno));
|
|
}
|
|
}
|
|
|
|
|
|
exit_free:
|
|
exit_free:
|
|
@@ -619,7 +727,7 @@ static int do_getnext(int argc, char **argv)
|
|
key = malloc(info.key_size);
|
|
key = malloc(info.key_size);
|
|
nextkey = malloc(info.key_size);
|
|
nextkey = malloc(info.key_size);
|
|
if (!key || !nextkey) {
|
|
if (!key || !nextkey) {
|
|
- err("mem alloc failed");
|
|
|
|
|
|
+ p_err("mem alloc failed");
|
|
err = -1;
|
|
err = -1;
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
@@ -636,22 +744,34 @@ static int do_getnext(int argc, char **argv)
|
|
|
|
|
|
err = bpf_map_get_next_key(fd, key, nextkey);
|
|
err = bpf_map_get_next_key(fd, key, nextkey);
|
|
if (err) {
|
|
if (err) {
|
|
- err("can't get next key: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("can't get next key: %s", strerror(errno));
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
|
|
|
|
- if (key) {
|
|
|
|
- printf("key:\n");
|
|
|
|
- fprint_hex(stdout, key, info.key_size, " ");
|
|
|
|
- printf("\n");
|
|
|
|
|
|
+ if (json_output) {
|
|
|
|
+ jsonw_start_object(json_wtr);
|
|
|
|
+ if (key) {
|
|
|
|
+ jsonw_name(json_wtr, "key");
|
|
|
|
+ print_hex_data_json(key, info.key_size);
|
|
|
|
+ } else {
|
|
|
|
+ jsonw_null_field(json_wtr, "key");
|
|
|
|
+ }
|
|
|
|
+ jsonw_name(json_wtr, "next_key");
|
|
|
|
+ print_hex_data_json(nextkey, info.key_size);
|
|
|
|
+ jsonw_end_object(json_wtr);
|
|
} else {
|
|
} else {
|
|
- printf("key: None\n");
|
|
|
|
|
|
+ if (key) {
|
|
|
|
+ printf("key:\n");
|
|
|
|
+ fprint_hex(stdout, key, info.key_size, " ");
|
|
|
|
+ printf("\n");
|
|
|
|
+ } else {
|
|
|
|
+ printf("key: None\n");
|
|
|
|
+ }
|
|
|
|
+ printf("next key:\n");
|
|
|
|
+ fprint_hex(stdout, nextkey, info.key_size, " ");
|
|
|
|
+ printf("\n");
|
|
}
|
|
}
|
|
|
|
|
|
- printf("next key:\n");
|
|
|
|
- fprint_hex(stdout, nextkey, info.key_size, " ");
|
|
|
|
- printf("\n");
|
|
|
|
-
|
|
|
|
exit_free:
|
|
exit_free:
|
|
free(nextkey);
|
|
free(nextkey);
|
|
free(key);
|
|
free(key);
|
|
@@ -677,7 +797,7 @@ static int do_delete(int argc, char **argv)
|
|
|
|
|
|
key = malloc(info.key_size);
|
|
key = malloc(info.key_size);
|
|
if (!key) {
|
|
if (!key) {
|
|
- err("mem alloc failed");
|
|
|
|
|
|
+ p_err("mem alloc failed");
|
|
err = -1;
|
|
err = -1;
|
|
goto exit_free;
|
|
goto exit_free;
|
|
}
|
|
}
|
|
@@ -688,22 +808,34 @@ static int do_delete(int argc, char **argv)
|
|
|
|
|
|
err = bpf_map_delete_elem(fd, key);
|
|
err = bpf_map_delete_elem(fd, key);
|
|
if (err)
|
|
if (err)
|
|
- err("delete failed: %s\n", strerror(errno));
|
|
|
|
|
|
+ p_err("delete failed: %s", strerror(errno));
|
|
|
|
|
|
exit_free:
|
|
exit_free:
|
|
free(key);
|
|
free(key);
|
|
close(fd);
|
|
close(fd);
|
|
|
|
|
|
|
|
+ if (!err && json_output)
|
|
|
|
+ jsonw_null(json_wtr);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
static int do_pin(int argc, char **argv)
|
|
static int do_pin(int argc, char **argv)
|
|
{
|
|
{
|
|
- return do_pin_any(argc, argv, bpf_map_get_fd_by_id);
|
|
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ err = do_pin_any(argc, argv, bpf_map_get_fd_by_id);
|
|
|
|
+ if (!err && json_output)
|
|
|
|
+ jsonw_null(json_wtr);
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
static int do_help(int argc, char **argv)
|
|
static int do_help(int argc, char **argv)
|
|
{
|
|
{
|
|
|
|
+ if (json_output) {
|
|
|
|
+ jsonw_null(json_wtr);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
fprintf(stderr,
|
|
fprintf(stderr,
|
|
"Usage: %s %s show [MAP]\n"
|
|
"Usage: %s %s show [MAP]\n"
|
|
" %s %s dump MAP\n"
|
|
" %s %s dump MAP\n"
|
|
@@ -718,6 +850,7 @@ static int do_help(int argc, char **argv)
|
|
" " HELP_SPEC_PROGRAM "\n"
|
|
" " HELP_SPEC_PROGRAM "\n"
|
|
" VALUE := { BYTES | MAP | PROG }\n"
|
|
" VALUE := { BYTES | MAP | PROG }\n"
|
|
" UPDATE_FLAGS := { any | exist | noexist }\n"
|
|
" UPDATE_FLAGS := { any | exist | noexist }\n"
|
|
|
|
+ " " HELP_SPEC_OPTIONS "\n"
|
|
"",
|
|
"",
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|
|
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
|