| 1 | |
| 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 |
|
| 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 | #ifndef __clang__
|
| 49 | #pragma GCC diagnostic ignored "-Wstringop-truncation"
|
| 50 | #endif
|
| 51 | __attribute__((unused))
|
| 52 | static inline char *safe_strncpy(char *dst, const char *src, size_t size)
|
| 53 | {
|
| 54 | if (!size)
|
| 55 | return dst;
|
| 56 | strncpy(dst, src, size - 1);
|
| 57 | dst[size - 1] = '\0';
|
| 58 | return dst;
|
| 59 | }
|
| 60 | #pragma GCC diagnostic pop
|
| 61 |
|
| 62 | #define __attach_tp(name) \
|
| 63 | ({ \
|
| 64 | if (bpf_program__type(skel->progs.name) != BPF_PROG_TYPE_TRACING)\
|
| 65 | return -EINVAL; \
|
| 66 | skel->links.name = bpf_program__attach(skel->progs.name); \
|
| 67 | if (!skel->links.name) \
|
| 68 | return -errno; \
|
| 69 | })
|
| 70 |
|
| 71 | #define sample_init_pre_load(skel) \
|
| 72 | ({ \
|
| 73 | skel->rodata->nr_cpus = libbpf_num_possible_cpus(); \
|
| 74 | sample_setup_maps((struct bpf_map *[]){ \
|
| 75 | skel->maps.rx_cnt, skel->maps.redir_err_cnt, \
|
| 76 | skel->maps.cpumap_enqueue_cnt, \
|
| 77 | skel->maps.cpumap_kthread_cnt, \
|
| 78 | skel->maps.exception_cnt, skel->maps.devmap_xmit_cnt, \
|
| 79 | skel->maps.devmap_xmit_cnt_multi }); \
|
| 80 | })
|
| 81 |
|
| 82 | #define DEFINE_SAMPLE_INIT(name) \
|
| 83 | static int sample_init(struct name *skel, int mask) \
|
| 84 | { \
|
| 85 | int ret; \
|
| 86 | ret = __sample_init(mask); \
|
| 87 | if (ret < 0) \
|
| 88 | return ret; \
|
| 89 | if (mask & SAMPLE_REDIRECT_MAP_CNT) \
|
| 90 | __attach_tp(tp_xdp_redirect_map); \
|
| 91 | if (mask & SAMPLE_REDIRECT_CNT) \
|
| 92 | __attach_tp(tp_xdp_redirect); \
|
| 93 | if (mask & SAMPLE_REDIRECT_ERR_MAP_CNT) \
|
| 94 | __attach_tp(tp_xdp_redirect_map_err); \
|
| 95 | if (mask & SAMPLE_REDIRECT_ERR_CNT) \
|
| 96 | __attach_tp(tp_xdp_redirect_err); \
|
| 97 | if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) \
|
| 98 | __attach_tp(tp_xdp_cpumap_enqueue); \
|
| 99 | if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) \
|
| 100 | __attach_tp(tp_xdp_cpumap_kthread); \
|
| 101 | if (mask & SAMPLE_EXCEPTION_CNT) \
|
| 102 | __attach_tp(tp_xdp_exception); \
|
| 103 | if (mask & SAMPLE_DEVMAP_XMIT_CNT) \
|
| 104 | __attach_tp(tp_xdp_devmap_xmit); \
|
| 105 | if (mask & SAMPLE_DEVMAP_XMIT_CNT_MULTI) \
|
| 106 | __attach_tp(tp_xdp_devmap_xmit_multi); \
|
| 107 | return 0; \
|
| 108 | }
|
| 109 |
|
| 110 | #endif
|