1 // SPDX-License-Identifier: GPL-2.0-only 2 #ifndef XDP_SAMPLE_USER_H 3 #define XDP_SAMPLE_USER_H 4 5 #include <bpf/libbpf.h> 6 #include <linux/compiler.h> 7 8 #include "xdp_sample_shared.h" 9 10 enum stats_mask { 11 _SAMPLE_REDIRECT_MAP = 1U << 0, 12 SAMPLE_RX_CNT = 1U << 1, 13 SAMPLE_REDIRECT_ERR_CNT = 1U << 2, 14 SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3, 15 SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, 16 SAMPLE_EXCEPTION_CNT = 1U << 5, 17 SAMPLE_DEVMAP_XMIT_CNT = 1U << 6, 18 SAMPLE_REDIRECT_CNT = 1U << 7, 19 SAMPLE_REDIRECT_MAP_CNT = SAMPLE_REDIRECT_CNT | _SAMPLE_REDIRECT_MAP, 20 SAMPLE_REDIRECT_ERR_MAP_CNT = SAMPLE_REDIRECT_ERR_CNT | _SAMPLE_REDIRECT_MAP, 21 SAMPLE_DEVMAP_XMIT_CNT_MULTI = 1U << 8, 22 SAMPLE_SKIP_HEADING = 1U << 9, 23 }; 24 25 /* Exit return codes */ 26 #define EXIT_OK 0 27 #define EXIT_FAIL 1 28 #define EXIT_FAIL_OPTION 2 29 #define EXIT_FAIL_XDP 3 30 #define EXIT_FAIL_BPF 4 31 #define EXIT_FAIL_MEM 5 32 33 int sample_setup_maps(struct bpf_map **maps); 34 int __sample_init(int mask); 35 void sample_exit(int status); 36 int sample_run(int interval, void (*post_cb)(void *), void *ctx); 37 38 void sample_switch_mode(void); 39 int sample_install_xdp(struct bpf_program *xdp_prog, int ifindex, bool generic, 40 bool force); 41 void sample_usage(char *argv[], const struct option *long_options, 42 const char *doc, int mask, bool error); 43 44 const char *get_driver_name(int ifindex); 45 int get_mac_addr(int ifindex, void *mac_addr); 46 47 #pragma GCC diagnostic push 48 #pragma GCC diagnostic ignored "-Wstringop-truncation" 49 __attribute__((unused)) 50 static inline char *safe_strncpy(char *dst, const char *src, size_t size) 51 { 52 if (!size) 53 return dst; 54 strncpy(dst, src, size - 1); 55 dst[size - 1] = '\0'; 56 return dst; 57 } 58 #pragma GCC diagnostic pop 59 60 #define __attach_tp(name) \ 61 ({ \ 62 if (!bpf_program__is_tracing(skel->progs.name)) \ 63 return -EINVAL; \ 64 skel->links.name = bpf_program__attach(skel->progs.name); \ 65 if (!skel->links.name) \ 66 return -errno; \ 67 }) 68 69 #define sample_init_pre_load(skel) \ 70 ({ \ 71 skel->rodata->nr_cpus = libbpf_num_possible_cpus(); \ 72 sample_setup_maps((struct bpf_map *[]){ \ 73 skel->maps.rx_cnt, skel->maps.redir_err_cnt, \ 74 skel->maps.cpumap_enqueue_cnt, \ 75 skel->maps.cpumap_kthread_cnt, \ 76 skel->maps.exception_cnt, skel->maps.devmap_xmit_cnt, \ 77 skel->maps.devmap_xmit_cnt_multi }); \ 78 }) 79 80 #define DEFINE_SAMPLE_INIT(name) \ 81 static int sample_init(struct name *skel, int mask) \ 82 { \ 83 int ret; \ 84 ret = __sample_init(mask); \ 85 if (ret < 0) \ 86 return ret; \ 87 if (mask & SAMPLE_REDIRECT_MAP_CNT) \ 88 __attach_tp(tp_xdp_redirect_map); \ 89 if (mask & SAMPLE_REDIRECT_CNT) \ 90 __attach_tp(tp_xdp_redirect); \ 91 if (mask & SAMPLE_REDIRECT_ERR_MAP_CNT) \ 92 __attach_tp(tp_xdp_redirect_map_err); \ 93 if (mask & SAMPLE_REDIRECT_ERR_CNT) \ 94 __attach_tp(tp_xdp_redirect_err); \ 95 if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) \ 96 __attach_tp(tp_xdp_cpumap_enqueue); \ 97 if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) \ 98 __attach_tp(tp_xdp_cpumap_kthread); \ 99 if (mask & SAMPLE_EXCEPTION_CNT) \ 100 __attach_tp(tp_xdp_exception); \ 101 if (mask & SAMPLE_DEVMAP_XMIT_CNT) \ 102 __attach_tp(tp_xdp_devmap_xmit); \ 103 if (mask & SAMPLE_DEVMAP_XMIT_CNT_MULTI) \ 104 __attach_tp(tp_xdp_devmap_xmit_multi); \ 105 return 0; \ 106 } 107 108 #endif 109