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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <rte_log.h>
#include <rte_common.h>
#include <rte_config.h>
#ifndef MR_STRING_MAX
#define MR_STRING_MAX 2048
#endif
#ifndef MR_SYMBOL_MAX
#define MR_SYMBOL_MAX 64
#endif
#ifndef MR_TOKENS_MAX
#define MR_TOKENS_MAX 512
#endif
#ifndef MR_BURST_MAX
#define MR_BURST_MAX 512
#endif
#ifndef MR_APP_MAX
#define MR_APP_MAX 64
#endif
#ifndef MR_CONS_MAX
#define MR_CONS_MAX 128
#endif
#ifndef MR_PROD_MAX
#define MR_PROD_MAX 128
#endif
#ifndef MR_SID_MAX
#define MR_SID_MAX RTE_MAX_LCORE
#endif
#ifndef MR_GSID_MAX
#define MR_GSID_MAX RTE_MAX_LCORE
#endif
#ifndef MR_VDEV_MAX
#define MR_VDEV_MAX 512
#endif
#ifndef MR_SOCKET_MAX
#define MR_SOCKET_MAX RTE_MAX_NUMA_NODES
#endif
#ifndef MR_PHYDEV_MAX
#define MR_PHYDEV_MAX RTE_MAX_ETHPORTS
#endif
typedef uint64_t cpu_mask_t;
typedef uint32_t port_id_t;
typedef uint32_t queue_id_t;
typedef uint32_t thread_id_t;
typedef uint32_t app_id_t;
typedef uint32_t flags_t;
typedef int32_t cpu_id_t;
typedef int32_t socket_id_t;
typedef uint32_t hash_t;
#define MR_SOCKET_ANY -1
#define MR_CPU_ID_ANY -1
#ifndef container_of
#ifdef __GNUC__
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type,member));})
#else
#define container_of(ptr, type,member) \
((type *)((char *)(ptr) - offsetof(type, member)))
#endif
#endif
/* ================================= VISUAL STUDIO ============================== */
#ifdef _MSC_VER
#define rte_cpu_to_be_16(x) htons(x)
#define rte_cpu_to_be_32(x) htonl(x)
#define rte_be_to_cpu_32(x) ntohl(x)
#define likely(x) x
#define unlikely(x) x
#define __thread __declspec(thread)
#define __builtin_popcountll(x) x
#define rte_atomic64_t uint64_t
#endif
/* ================================= LOGGER ======================================= */
#include <systemd/sd-journal.h>
extern unsigned int g_logger_to_stdout;
extern unsigned int g_logger_level;
extern unsigned int g_eal_started;
#define MR_LOG(LEVEL, ...) \
do { \
if(g_logger_to_stdout && LEVEL <= g_logger_level) \
{ \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
if(LEVEL <= g_logger_level) \
{ \
sd_journal_print(LEVEL, ##__VA_ARGS__); \
} \
}while(0)
#define MR_INFO(...) MR_LOG(LOG_INFO, ##__VA_ARGS__)
#define MR_DEBUG(...) MR_LOG(LOG_DEBUG, ##__VA_ARGS__)
#define MR_ERROR(...) MR_LOG(LOG_ERR, ##__VA_ARGS__)
#define MR_WARNING(...) MR_LOG(LOG_WARNING, ##__VA_ARGS__)
/* ============================== ERROR HANDLER ================================== */
#define MR_VERIFY_2(exp, fmt, ...) \
do { \
if(!(exp)) { \
fprintf(stderr, "%s(%s:%d): Verify failure, " fmt "\n", \
__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__); \
abort(); \
} \
} while(0)
#define MR_VERIFY_1(exp) MR_VERIFY_2(exp, "")
#define MR_VERIFY(exp) MR_VERIFY_1(exp)
#define MR_VERIFY_MALLOC(ver) \
do { \
MR_VERIFY_2(ver != NULL, "Not enough memory space, Please restart the program."); \
} while(0)
#include <rte_errno.h>
#define MR_STR_ERRNO(error) \
({ \
char __strerrno[MR_STRING_MAX]; \
snprintf(__strerrno, sizeof(__strerrno), "%s(errno=%d)", strerror(error), error); \
__strerrno; \
})
#define MR_CFGERR_LOST_KEY(file, section, key) \
do { \
MR_WARNING("Configure File %s, section '%s', key '%s': required key lost. ", \
file, section, key); \
}while(0)
#define MR_CFGERR_INVALID_FORMAT(file, section, key) \
do { \
MR_WARNING("Configure File %s, section '%s', key '%s': invalid value or format. ", \
file, section, key); \
}while(0)
#define MR_CFGERR_INVALID_VALUE(file, section, key, fmt, ...) \
do { \
char __local_fmt[MR_STRING_MAX]; int curser = 0; \
curser += snprintf(__local_fmt + curser, sizeof(__local_fmt) - curser, \
"In cfgfile '%s', section '%s', key '%s': invalid value, ", \
file, section, key); \
curser += snprintf(__local_fmt + curser, sizeof(__local_fmt) - curser, \
fmt, ## __VA_ARGS__); \
MR_WARNING("%s", __local_fmt); \
} while(0)
static inline const char * __str_rte_errno()
{
return rte_strerror(rte_errno);
}
#define MR_STR_RTEERRNO __str_rte_errno
/* ================================= RETURN ========================================*/
#define RT_IGNORE -2
#define RT_ERR -1
#define RT_SUCCESS 0
#define RT_HANDLER()
/* ================================= STRING ======================================== */
static inline unsigned strstrip(char *str, unsigned len)
{
int newlen = len;
if (len == 0)
return 0;
if (isspace(str[len - 1])) {
/* strip trailing whitespace */
while (newlen > 0 && isspace(str[newlen - 1]))
str[--newlen] = '\0';
}
if (isspace(str[0])) {
/* strip leading whitespace */
int i, start = 1;
while (isspace(str[start]) && start < newlen)
start++
; /* do nothing */
newlen -= start;
for (i = 0; i < newlen; i++)
str[i] = str[i + start];
str[i] = '\0';
}
return newlen;
}
static inline int parser_uint(const char * str)
{
char * strptr;
unsigned int ret = strtol(str, &strptr, 0);
if (ret == 0 && strptr == str) return -1;
return ret;
}
/* ================================= MALLOC/FREE ================================ */
#define ZMALLOC(size) (rte_zmalloc(NULL, size, 0))
#define FREE(ptr) (rte_free(ptr))
#define LIBC_MALLOC(size) (malloc(size))
//TODO: 支持更多比特位的掩码
typedef uint64_t mask_t;
/* ================================= MASK ======================================== */
static unsigned int inline mask_popcnt(mask_t mask)
{
return __builtin_popcountll(mask);
}
static unsigned int inline mask_is_set(mask_t mask, unsigned int id)
{
return !!(mask & (1ULL << id));
}
static int inline cpu_set_location(cpu_set_t * cpu_set_p, unsigned int id)
{
unsigned int bit_count = 0;
for (unsigned bit_iter = 0; bit_iter < CPU_SETSIZE; bit_iter++)
{
if (CPU_ISSET(bit_iter, cpu_set_p))
{
if (bit_count == id) return bit_iter;
else bit_count++;
}
}
return -1;
}
static int inline str_to_mask(const char * str, mask_t * out_mask)
{
/* 先复制一份,避免修改传入参数 */
char __str[MR_STRING_MAX] = { 0 };
strncpy(__str, str, sizeof(__str) - 1);
mask_t __mask = 0;
/* 按逗号拆分 */
int nr_str_tokens = 0;
char * __saveptr;
for (const char * token = strtok_r(__str, ",", &__saveptr);
token != NULL; token = strtok_r(NULL, ",", &__saveptr))
{
int core_id = parser_uint(token);
if (core_id < 0) goto errout;
nr_str_tokens++;
__mask |= 1ULL << core_id;
}
if (nr_str_tokens == 0) goto errout;
*out_mask = __mask;
return RT_SUCCESS;
errout:
return RT_ERR;
}
/* =============================== PROFILE ====================================== */
static inline void timespec_diff(struct timespec * start, struct timespec * end,
struct timespec * result)
{
if ((end->tv_nsec - start->tv_nsec) < 0)
{
result->tv_sec = end->tv_sec - start->tv_sec - 1;
result->tv_nsec = end->tv_nsec - start->tv_nsec + 1000000000;
}
else
{
result->tv_sec = end->tv_sec - start->tv_sec;
result->tv_nsec = end->tv_nsec - start->tv_nsec;
}
return;
}
/* =============================== G_VXLAN_DEFINE =============================== */
struct g_vxlan_hdr
{
unsigned char flags;
/*------------byte delim -------*/
unsigned char reserved[3];
/*--------int delim -------*/
unsigned char vlan_id_half_high;
unsigned char link_layer_type : 4; /* 二层报文封装格式 */
unsigned char vlan_id_half_low : 4;
unsigned int dir : 1;
unsigned int link_id : 6;
unsigned int online_test : 1;
unsigned int r7 : 1;
unsigned int r6 : 1;
unsigned int r5 : 1;
unsigned int r4 : 1;
unsigned int vni_flag : 1;
unsigned int r2 : 1;
unsigned int r1 : 1;
unsigned int r0 : 1;
};
#define G_VXLAN_DPORT (4789)
#define G_VXLAN_INNER_LINK_TYPE_ETH (0x0)
#define G_VXLAN_INNER_LINK_TYPE_PPP (0x8)
#define G_VXLAN_INNER_LINK_TYPE_HDLC (0xC)
static inline int mr_thread_setname(pthread_t id, const char *name)
{
return pthread_setname_np(id, name);;
}
#ifdef __cplusplus
}
#endif
|