forked from xdp-project/xdp-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libxdp_internal.h
140 lines (116 loc) · 3.77 KB
/
libxdp_internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef __LIBXDP_LIBXDP_INTERNAL_H
#define __LIBXDP_LIBXDP_INTERNAL_H
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <linux/err.h>
#include <xdp/libxdp.h>
#define LIBXDP_HIDE_SYMBOL __attribute__((visibility("hidden")))
#define __unused __attribute__((unused))
#define __printf(a, b) __attribute__((format(printf, a, b)))
static inline int try_snprintf(char *buf, size_t buf_len, const char *format, ...)
{
va_list args;
int len;
va_start(args, format);
len = vsnprintf(buf, buf_len, format, args);
va_end(args);
if (len < 0)
return -EINVAL;
else if ((size_t)len >= buf_len)
return -ENAMETOOLONG;
return 0;
}
LIBXDP_HIDE_SYMBOL __printf(2, 3) void libxdp_print(enum libxdp_print_level level,
const char *format, ...);
#define __pr(level, fmt, ...) \
do { \
libxdp_print(level, "libxdp: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warn(fmt, ...) __pr(LIBXDP_WARN, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) __pr(LIBXDP_INFO, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) __pr(LIBXDP_DEBUG, fmt, ##__VA_ARGS__)
LIBXDP_HIDE_SYMBOL int check_xdp_prog_version(const struct btf *btf, const char *name,
__u32 *version);
LIBXDP_HIDE_SYMBOL struct xdp_program *xdp_program__clone(struct xdp_program *prog);
#define min(x, y) ((x) < (y) ? x : y)
#define max(x, y) ((x) > (y) ? x : y)
#ifndef offsetof
#define offsetof(type, member) ((size_t) & ((type *)0)->member)
#endif
#ifndef offsetofend
#define offsetofend(TYPE, FIELD) (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
#endif
#ifndef container_of
#define container_of(ptr, type, member) \
({ \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); \
})
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
/* OPTS macros, from libbpf_internal.h */
static inline bool libxdp_is_mem_zeroed(const char *p, ssize_t len)
{
while (len > 0) {
if (*p)
return false;
p++;
len--;
}
return true;
}
static inline bool libxdp_validate_opts(const char *opts,
size_t opts_sz, size_t user_sz,
const char *type_name)
{
if (user_sz < sizeof(size_t)) {
pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
return false;
}
if (!libxdp_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
pr_warn("%s has non-zero extra bytes\n", type_name);
return false;
}
return true;
}
#define OPTS_VALID(opts, type) \
(!(opts) || libxdp_validate_opts((const char *)opts, \
offsetofend(struct type, \
type##__last_field), \
(opts)->sz, #type))
#define OPTS_HAS(opts, field) \
((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
#define OPTS_GET(opts, field, fallback_value) \
(OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
#define OPTS_SET(opts, field, value) \
do { \
if (OPTS_HAS(opts, field)) \
(opts)->field = value; \
} while (0)
#define OPTS_ZEROED(opts, last_nonzero_field) \
({ \
ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
!(opts) || libxdp_is_mem_zeroed((const void *)opts + __off, \
(opts)->sz - __off); \
})
/* handle direct returned errors */
static inline int libxdp_err(int ret)
{
if (ret < 0)
errno = -ret;
return ret;
}
/* handle error for pointer-returning APIs, err is assumed to be < 0 always */
static inline void *libxdp_err_ptr(int err, bool ret_null)
{
/* set errno on error, this doesn't break anything */
errno = -err;
if (ret_null)
return NULL;
/* legacy: encode err as ptr */
return ERR_PTR(err);
}
#endif /* __LIBXDP_LIBXDP_INTERNAL_H */