1 // SPDX-License-Identifier: GPL-2.0-only 2 #include "bpftool_helpers.h" 3 #include <unistd.h> 4 #include <string.h> 5 #include <stdbool.h> 6 7 #define BPFTOOL_PATH_MAX_LEN 64 8 #define BPFTOOL_FULL_CMD_MAX_LEN 512 9 10 #define BPFTOOL_DEFAULT_PATH "tools/sbin/bpftool" 11 12 static int detect_bpftool_path(char *buffer) 13 { 14 char tmp[BPFTOOL_PATH_MAX_LEN]; 15 16 /* Check default bpftool location (will work if we are running the 17 * default flavor of test_progs) 18 */ 19 snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "./%s", BPFTOOL_DEFAULT_PATH); 20 if (access(tmp, X_OK) == 0) { 21 strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN); 22 return 0; 23 } 24 25 /* Check alternate bpftool location (will work if we are running a 26 * specific flavor of test_progs, e.g. cpuv4 or no_alu32) 27 */ 28 snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "../%s", BPFTOOL_DEFAULT_PATH); 29 if (access(tmp, X_OK) == 0) { 30 strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN); 31 return 0; 32 } 33 34 /* Failed to find bpftool binary */ 35 return 1; 36 } 37 38 static int run_command(char *args, char *output_buf, size_t output_max_len) 39 { 40 static char bpftool_path[BPFTOOL_PATH_MAX_LEN] = {0}; 41 bool suppress_output = !(output_buf && output_max_len); 42 char command[BPFTOOL_FULL_CMD_MAX_LEN]; 43 FILE *f; 44 int ret; 45 46 /* Detect and cache bpftool binary location */ 47 if (bpftool_path[0] == 0 && detect_bpftool_path(bpftool_path)) 48 return 1; 49 50 ret = snprintf(command, BPFTOOL_FULL_CMD_MAX_LEN, "%s %s%s", 51 bpftool_path, args, 52 suppress_output ? " > /dev/null 2>&1" : ""); 53 54 f = popen(command, "r"); 55 if (!f) 56 return 1; 57 58 if (!suppress_output) 59 fread(output_buf, 1, output_max_len, f); 60 ret = pclose(f); 61 62 return ret; 63 } 64 65 int run_bpftool_command(char *args) 66 { 67 return run_command(args, NULL, 0); 68 } 69 70 int get_bpftool_command_output(char *args, char *output_buf, size_t output_max_len) 71 { 72 return run_command(args, output_buf, output_max_len); 73 } 74 75