File Index
Files and directories
Sign in
FILE

token.c

File preview with syntax highlighting.

linux-6.19.14/tools/bpf/bpftool/token.c C
  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
 23static 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
 33static 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
 41static 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
 60static 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
 79static 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
 98static 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
116static 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
136static 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
146static 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
175static int do_show(int argc, char **argv)
176{
177	if (argc)
178		return BAD_ARG();
179
180	return show_token_info();
181}
182
183static 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
200static const struct cmd cmds[] = {
201	{ "show",	do_show },
202	{ "list",	do_show },
203	{ "help",	do_help },
204	{ 0 }
205};
206
207int do_token(int argc, char **argv)
208{
209	return cmd_select(cmds, argc, argv, do_help);
210}
~/ Read-only file preview.