0001
0002 #ifndef XDP_SAMPLE_USER_H
0003 #define XDP_SAMPLE_USER_H
0004
0005 #include <bpf/libbpf.h>
0006 #include <linux/compiler.h>
0007
0008 #include "xdp_sample_shared.h"
0009
0010 enum stats_mask {
0011 _SAMPLE_REDIRECT_MAP = 1U << 0,
0012 SAMPLE_RX_CNT = 1U << 1,
0013 SAMPLE_REDIRECT_ERR_CNT = 1U << 2,
0014 SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3,
0015 SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4,
0016 SAMPLE_EXCEPTION_CNT = 1U << 5,
0017 SAMPLE_DEVMAP_XMIT_CNT = 1U << 6,
0018 SAMPLE_REDIRECT_CNT = 1U << 7,
0019 SAMPLE_REDIRECT_MAP_CNT = SAMPLE_REDIRECT_CNT | _SAMPLE_REDIRECT_MAP,
0020 SAMPLE_REDIRECT_ERR_MAP_CNT = SAMPLE_REDIRECT_ERR_CNT | _SAMPLE_REDIRECT_MAP,
0021 SAMPLE_DEVMAP_XMIT_CNT_MULTI = 1U << 8,
0022 SAMPLE_SKIP_HEADING = 1U << 9,
0023 };
0024
0025
0026 #define EXIT_OK 0
0027 #define EXIT_FAIL 1
0028 #define EXIT_FAIL_OPTION 2
0029 #define EXIT_FAIL_XDP 3
0030 #define EXIT_FAIL_BPF 4
0031 #define EXIT_FAIL_MEM 5
0032
0033 int sample_setup_maps(struct bpf_map **maps);
0034 int __sample_init(int mask);
0035 void sample_exit(int status);
0036 int sample_run(int interval, void (*post_cb)(void *), void *ctx);
0037
0038 void sample_switch_mode(void);
0039 int sample_install_xdp(struct bpf_program *xdp_prog, int ifindex, bool generic,
0040 bool force);
0041 void sample_usage(char *argv[], const struct option *long_options,
0042 const char *doc, int mask, bool error);
0043
0044 const char *get_driver_name(int ifindex);
0045 int get_mac_addr(int ifindex, void *mac_addr);
0046
0047 #pragma GCC diagnostic push
0048 #ifndef __clang__
0049 #pragma GCC diagnostic ignored "-Wstringop-truncation"
0050 #endif
0051 __attribute__((unused))
0052 static inline char *safe_strncpy(char *dst, const char *src, size_t size)
0053 {
0054 if (!size)
0055 return dst;
0056 strncpy(dst, src, size - 1);
0057 dst[size - 1] = '\0';
0058 return dst;
0059 }
0060 #pragma GCC diagnostic pop
0061
0062 #define __attach_tp(name) \
0063 ({ \
0064 if (bpf_program__type(skel->progs.name) != BPF_PROG_TYPE_TRACING)\
0065 return -EINVAL; \
0066 skel->links.name = bpf_program__attach(skel->progs.name); \
0067 if (!skel->links.name) \
0068 return -errno; \
0069 })
0070
0071 #define sample_init_pre_load(skel) \
0072 ({ \
0073 skel->rodata->nr_cpus = libbpf_num_possible_cpus(); \
0074 sample_setup_maps((struct bpf_map *[]){ \
0075 skel->maps.rx_cnt, skel->maps.redir_err_cnt, \
0076 skel->maps.cpumap_enqueue_cnt, \
0077 skel->maps.cpumap_kthread_cnt, \
0078 skel->maps.exception_cnt, skel->maps.devmap_xmit_cnt, \
0079 skel->maps.devmap_xmit_cnt_multi }); \
0080 })
0081
0082 #define DEFINE_SAMPLE_INIT(name) \
0083 static int sample_init(struct name *skel, int mask) \
0084 { \
0085 int ret; \
0086 ret = __sample_init(mask); \
0087 if (ret < 0) \
0088 return ret; \
0089 if (mask & SAMPLE_REDIRECT_MAP_CNT) \
0090 __attach_tp(tp_xdp_redirect_map); \
0091 if (mask & SAMPLE_REDIRECT_CNT) \
0092 __attach_tp(tp_xdp_redirect); \
0093 if (mask & SAMPLE_REDIRECT_ERR_MAP_CNT) \
0094 __attach_tp(tp_xdp_redirect_map_err); \
0095 if (mask & SAMPLE_REDIRECT_ERR_CNT) \
0096 __attach_tp(tp_xdp_redirect_err); \
0097 if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) \
0098 __attach_tp(tp_xdp_cpumap_enqueue); \
0099 if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) \
0100 __attach_tp(tp_xdp_cpumap_kthread); \
0101 if (mask & SAMPLE_EXCEPTION_CNT) \
0102 __attach_tp(tp_xdp_exception); \
0103 if (mask & SAMPLE_DEVMAP_XMIT_CNT) \
0104 __attach_tp(tp_xdp_devmap_xmit); \
0105 if (mask & SAMPLE_DEVMAP_XMIT_CNT_MULTI) \
0106 __attach_tp(tp_xdp_devmap_xmit_multi); \
0107 return 0; \
0108 }
0109
0110 #endif