111 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#ifndef XDP_SAMPLE_USER_H3#define XDP_SAMPLE_USER_H4 5#include <bpf/libbpf.h>6#include <linux/compiler.h>7 8#include "xdp_sample_shared.h"9 10enum 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 027#define EXIT_FAIL 128#define EXIT_FAIL_OPTION 229#define EXIT_FAIL_XDP 330#define EXIT_FAIL_BPF 431#define EXIT_FAIL_MEM 532 33int sample_setup_maps(struct bpf_map **maps);34int __sample_init(int mask);35void sample_exit(int status);36int sample_run(int interval, void (*post_cb)(void *), void *ctx);37 38void sample_switch_mode(void);39int sample_install_xdp(struct bpf_program *xdp_prog, int ifindex, bool generic,40 bool force);41void sample_usage(char *argv[], const struct option *long_options,42 const char *doc, int mask, bool error);43 44const char *get_driver_name(int ifindex);45int get_mac_addr(int ifindex, void *mac_addr);46 47#pragma GCC diagnostic push48#ifndef __clang__49#pragma GCC diagnostic ignored "-Wstringop-truncation"50#endif51__attribute__((unused))52static 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 pop61 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#endif111