]>
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)
29 fprintf(stderr
, "Usage: ... bpf [ import UDS_FILE ] [ run CMD ] [ debug ]\n\n");
30 fprintf(stderr
, "Where UDS_FILE provides the name of a unix domain socket file\n");
31 fprintf(stderr
, "to import eBPF maps and the optional CMD denotes the command\n");
32 fprintf(stderr
, "to be executed (default: \'%s\').\n", BPF_DEFAULT_CMD
);
35 static int bpf_num_env_entries(void)
40 for (num
= 0, envp
= environ
; *envp
!= NULL
; envp
++)
45 static int parse_bpf(struct exec_util
*eu
, int argc
, char **argv
)
47 char **argv_run
= argv_default
, **envp_run
, *tmp
;
48 int ret
, i
, env_old
, env_num
, env_map
;
49 const char *bpf_uds_name
= NULL
;
50 int fds
[BPF_SCM_MAX_FDS
];
51 struct bpf_map_aux aux
;
57 if (matches(*argv
, "run") == 0) {
61 } else if (matches(*argv
, "import") == 0) {
64 } else if (matches(*argv
, "debug") == 0 ||
65 matches(*argv
, "dbg") == 0) {
68 "No trace pipe, tracefs not mounted?\n");
79 fprintf(stderr
, "bpf: No import parameter provided!\n");
84 if (argv_run
!= argv_default
&& argc
== 0) {
85 fprintf(stderr
, "bpf: No run command provided!\n");
90 memset(fds
, 0, sizeof(fds
));
91 memset(&aux
, 0, sizeof(aux
));
93 ret
= bpf_recv_map_fds(bpf_uds_name
, fds
, &aux
, ARRAY_SIZE(fds
));
95 fprintf(stderr
, "bpf: Could not receive fds!\n");
99 if (aux
.num_ent
== 0) {
104 env_old
= bpf_num_env_entries();
105 env_num
= env_old
+ aux
.num_ent
+ 2;
106 env_map
= env_old
+ 1;
108 envp_run
= malloc(sizeof(*envp_run
) * env_num
);
110 fprintf(stderr
, "bpf: No memory left to allocate env!\n");
114 for (i
= 0; i
< env_old
; i
++)
115 envp_run
[i
] = environ
[i
];
117 ret
= asprintf(&tmp
, "BPF_NUM_MAPS=%u", aux
.num_ent
);
121 envp_run
[env_old
] = tmp
;
123 for (i
= env_map
; i
< env_num
- 1; i
++) {
124 ret
= asprintf(&tmp
, "BPF_MAP%u=%u",
125 aux
.ent
[i
- env_map
].id
,
133 envp_run
[env_num
- 1] = NULL
;
135 return execvpe(argv_run
[0], argv_run
, envp_run
);
138 for (--i
; i
>= env_old
; i
--)
143 for (i
= 0; i
< aux
.num_ent
; i
++)
148 struct exec_util bpf_exec_util
= {
150 .parse_eopt
= parse_bpf
,