Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/bpf/bpftool/token.c
29267 views
1
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
/* Copyright (C) 2025 Didi Technology Co., Tao Chen */
3
4
#ifndef _GNU_SOURCE
5
#define _GNU_SOURCE
6
#endif
7
#include <errno.h>
8
#include <fcntl.h>
9
#include <stdbool.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <string.h>
13
#include <unistd.h>
14
#include <mntent.h>
15
#include <sys/types.h>
16
#include <sys/stat.h>
17
18
#include "json_writer.h"
19
#include "main.h"
20
21
#define MOUNTS_FILE "/proc/mounts"
22
23
static struct {
24
const char *header;
25
const char *key;
26
} sets[] = {
27
{"allowed_cmds", "delegate_cmds"},
28
{"allowed_maps", "delegate_maps"},
29
{"allowed_progs", "delegate_progs"},
30
{"allowed_attachs", "delegate_attachs"},
31
};
32
33
static bool has_delegate_options(const char *mnt_ops)
34
{
35
return strstr(mnt_ops, "delegate_cmds") ||
36
strstr(mnt_ops, "delegate_maps") ||
37
strstr(mnt_ops, "delegate_progs") ||
38
strstr(mnt_ops, "delegate_attachs");
39
}
40
41
static char *get_delegate_value(char *opts, const char *key)
42
{
43
char *token, *rest, *ret = NULL;
44
45
if (!opts)
46
return NULL;
47
48
for (token = strtok_r(opts, ",", &rest); token;
49
token = strtok_r(NULL, ",", &rest)) {
50
if (strncmp(token, key, strlen(key)) == 0 &&
51
token[strlen(key)] == '=') {
52
ret = token + strlen(key) + 1;
53
break;
54
}
55
}
56
57
return ret;
58
}
59
60
static void print_items_per_line(char *input, int items_per_line)
61
{
62
char *str, *rest;
63
int cnt = 0;
64
65
if (!input)
66
return;
67
68
for (str = strtok_r(input, ":", &rest); str;
69
str = strtok_r(NULL, ":", &rest)) {
70
if (cnt % items_per_line == 0)
71
printf("\n\t ");
72
73
printf("%-20s", str);
74
cnt++;
75
}
76
}
77
78
#define ITEMS_PER_LINE 4
79
static void show_token_info_plain(struct mntent *mntent)
80
{
81
size_t i;
82
83
printf("token_info %s", mntent->mnt_dir);
84
85
for (i = 0; i < ARRAY_SIZE(sets); i++) {
86
char *opts, *value;
87
88
printf("\n\t%s:", sets[i].header);
89
opts = strdup(mntent->mnt_opts);
90
value = get_delegate_value(opts, sets[i].key);
91
print_items_per_line(value, ITEMS_PER_LINE);
92
free(opts);
93
}
94
95
printf("\n");
96
}
97
98
static void split_json_array_str(char *input)
99
{
100
char *str, *rest;
101
102
if (!input) {
103
jsonw_start_array(json_wtr);
104
jsonw_end_array(json_wtr);
105
return;
106
}
107
108
jsonw_start_array(json_wtr);
109
for (str = strtok_r(input, ":", &rest); str;
110
str = strtok_r(NULL, ":", &rest)) {
111
jsonw_string(json_wtr, str);
112
}
113
jsonw_end_array(json_wtr);
114
}
115
116
static void show_token_info_json(struct mntent *mntent)
117
{
118
size_t i;
119
120
jsonw_start_object(json_wtr);
121
jsonw_string_field(json_wtr, "token_info", mntent->mnt_dir);
122
123
for (i = 0; i < ARRAY_SIZE(sets); i++) {
124
char *opts, *value;
125
126
jsonw_name(json_wtr, sets[i].header);
127
opts = strdup(mntent->mnt_opts);
128
value = get_delegate_value(opts, sets[i].key);
129
split_json_array_str(value);
130
free(opts);
131
}
132
133
jsonw_end_object(json_wtr);
134
}
135
136
static int __show_token_info(struct mntent *mntent)
137
{
138
if (json_output)
139
show_token_info_json(mntent);
140
else
141
show_token_info_plain(mntent);
142
143
return 0;
144
}
145
146
static int show_token_info(void)
147
{
148
FILE *fp;
149
struct mntent *ent;
150
151
fp = setmntent(MOUNTS_FILE, "r");
152
if (!fp) {
153
p_err("Failed to open: %s", MOUNTS_FILE);
154
return -1;
155
}
156
157
if (json_output)
158
jsonw_start_array(json_wtr);
159
160
while ((ent = getmntent(fp)) != NULL) {
161
if (strncmp(ent->mnt_type, "bpf", 3) == 0) {
162
if (has_delegate_options(ent->mnt_opts))
163
__show_token_info(ent);
164
}
165
}
166
167
if (json_output)
168
jsonw_end_array(json_wtr);
169
170
endmntent(fp);
171
172
return 0;
173
}
174
175
static int do_show(int argc, char **argv)
176
{
177
if (argc)
178
return BAD_ARG();
179
180
return show_token_info();
181
}
182
183
static int do_help(int argc, char **argv)
184
{
185
if (json_output) {
186
jsonw_null(json_wtr);
187
return 0;
188
}
189
190
fprintf(stderr,
191
"Usage: %1$s %2$s { show | list }\n"
192
" %1$s %2$s help\n"
193
" " HELP_SPEC_OPTIONS " }\n"
194
"\n"
195
"",
196
bin_name, argv[-2]);
197
return 0;
198
}
199
200
static const struct cmd cmds[] = {
201
{ "show", do_show },
202
{ "list", do_show },
203
{ "help", do_help },
204
{ 0 }
205
};
206
207
int do_token(int argc, char **argv)
208
{
209
return cmd_select(cmds, argc, argv, do_help);
210
}
211
212