]>
git.proxmox.com Git - mirror_iproute2.git/blob - tc/e_bpf.c
2 * e_bpf.c BPF exec proxy
4 * This program is free software; you can distribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Daniel Borkmann <daniel@iogearbox.net>
23 #define BPF_DEFAULT_CMD "/bin/sh"
25 static char *argv_default
[] = { BPF_DEFAULT_CMD
, NULL
};
27 static void explain(void)
30 "Usage: ... bpf [ import UDS_FILE ] [ run CMD ]\n"
31 " ... bpf [ debug ]\n"
32 " ... bpf [ graft MAP_FILE ] [ key KEY ]\n"
33 " `... [ object-file OBJ_FILE ] [ type TYPE ] [ section NAME ] [ verbose ]\n"
34 " `... [ object-pinned PROG_FILE ]\n"
36 "Where UDS_FILE provides the name of a unix domain socket file\n"
37 "to import eBPF maps and the optional CMD denotes the command\n"
38 "to be executed (default: \'%s\').\n"
39 "Where MAP_FILE points to a pinned map, OBJ_FILE to an object file\n"
40 "and PROG_FILE to a pinned program. TYPE can be {cls, act}, where\n"
41 "\'cls\' is default. KEY is optional and can be inferred from the\n"
42 "section name, otherwise it needs to be provided.\n",
46 static int bpf_num_env_entries(void)
51 for (num
= 0, envp
= environ
; *envp
!= NULL
; envp
++)
56 static int parse_bpf(struct exec_util
*eu
, int argc
, char **argv
)
58 char **argv_run
= argv_default
, **envp_run
, *tmp
;
59 int ret
, i
, env_old
, env_num
, env_map
;
60 const char *bpf_uds_name
= NULL
;
61 int fds
[BPF_SCM_MAX_FDS
] = {};
62 struct bpf_map_aux aux
= {};
68 if (matches(*argv
, "run") == 0) {
72 } else if (matches(*argv
, "import") == 0) {
75 } else if (matches(*argv
, "debug") == 0 ||
76 matches(*argv
, "dbg") == 0) {
79 "No trace pipe, tracefs not mounted?\n");
81 } else if (matches(*argv
, "graft") == 0) {
82 const char *bpf_map_path
;
89 if (matches(*argv
, "key") == 0) {
91 if (get_unsigned(&key
, *argv
, 0)) {
92 fprintf(stderr
, "Illegal \"key\"\n");
98 return bpf_graft_map(bpf_map_path
, has_key
?
99 &key
: NULL
, argc
, argv
);
109 fprintf(stderr
, "bpf: No import parameter provided!\n");
114 if (argv_run
!= argv_default
&& argc
== 0) {
115 fprintf(stderr
, "bpf: No run command provided!\n");
120 ret
= bpf_recv_map_fds(bpf_uds_name
, fds
, &aux
, ARRAY_SIZE(fds
));
122 fprintf(stderr
, "bpf: Could not receive fds!\n");
126 if (aux
.num_ent
== 0) {
131 env_old
= bpf_num_env_entries();
132 env_num
= env_old
+ aux
.num_ent
+ 2;
133 env_map
= env_old
+ 1;
135 envp_run
= malloc(sizeof(*envp_run
) * env_num
);
137 fprintf(stderr
, "bpf: No memory left to allocate env!\n");
141 for (i
= 0; i
< env_old
; i
++)
142 envp_run
[i
] = environ
[i
];
144 ret
= asprintf(&tmp
, "BPF_NUM_MAPS=%u", aux
.num_ent
);
148 envp_run
[env_old
] = tmp
;
150 for (i
= env_map
; i
< env_num
- 1; i
++) {
151 ret
= asprintf(&tmp
, "BPF_MAP%u=%u",
152 aux
.ent
[i
- env_map
].id
,
160 envp_run
[env_num
- 1] = NULL
;
162 return execvpe(argv_run
[0], argv_run
, envp_run
);
165 for (--i
; i
>= env_old
; i
--)
170 for (i
= 0; i
< aux
.num_ent
; i
++)
175 struct exec_util bpf_exec_util
= {
177 .parse_eopt
= parse_bpf
,