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
|
/* SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2023 Cisco Systems, Inc.
*/
#ifndef _VNET_DEV_COUNTERS_H_
#define _VNET_DEV_COUNTERS_H_
#include <vnet/dev/dev.h>
typedef enum
{
VNET_DEV_CTR_DIR_NA,
VNET_DEV_CTR_DIR_RX,
VNET_DEV_CTR_DIR_TX,
} __clib_packed vnet_dev_counter_direction_t;
typedef enum
{
VNET_DEV_CTR_TYPE_RX_BYTES,
VNET_DEV_CTR_TYPE_RX_PACKETS,
VNET_DEV_CTR_TYPE_RX_DROPS,
VNET_DEV_CTR_TYPE_TX_BYTES,
VNET_DEV_CTR_TYPE_TX_PACKETS,
VNET_DEV_CTR_TYPE_TX_DROPS,
VNET_DEV_CTR_TYPE_VENDOR,
} __clib_packed vnet_dev_counter_type_t;
typedef enum
{
VNET_DEV_CTR_UNIT_NA,
VNET_DEV_CTR_UNIT_BYTES,
VNET_DEV_CTR_UNIT_PACKETS,
VNET_DEV_CTR_UNIT_DESCRIPTORS,
VNET_DEV_CTR_UNIT_BUFFERS,
} __clib_packed vnet_dev_counter_unit_t;
typedef struct vnet_dev_counter
{
char name[24];
uword user_data;
vnet_dev_counter_type_t type;
vnet_dev_counter_direction_t dir;
vnet_dev_counter_unit_t unit;
u16 index;
} vnet_dev_counter_t;
typedef struct vnet_dev_counter_main
{
u8 *desc;
u64 *counter_data;
u64 *counter_start;
u16 n_counters;
vnet_dev_counter_t counters[];
} vnet_dev_counter_main_t;
#define VNET_DEV_CTR_RX_BYTES(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_RX_BYTES, .dir = VNET_DEV_CTR_DIR_RX, \
.unit = VNET_DEV_CTR_UNIT_BYTES, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_TX_BYTES(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_TX_BYTES, .dir = VNET_DEV_CTR_DIR_TX, \
.unit = VNET_DEV_CTR_UNIT_BYTES, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_RX_PACKETS(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_RX_PACKETS, .dir = VNET_DEV_CTR_DIR_RX, \
.unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_TX_PACKETS(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_TX_PACKETS, .dir = VNET_DEV_CTR_DIR_TX, \
.unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_RX_DROPS(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_RX_DROPS, .dir = VNET_DEV_CTR_DIR_RX, \
.unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_TX_DROPS(p, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_TX_DROPS, .dir = VNET_DEV_CTR_DIR_TX, \
.unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__ \
}
#define VNET_DEV_CTR_VENDOR(p, d, u, n, ...) \
{ \
.type = VNET_DEV_CTR_TYPE_VENDOR, .user_data = (p), .name = n, \
.dir = VNET_DEV_CTR_DIR_##d, .unit = VNET_DEV_CTR_UNIT_##u, __VA_ARGS__ \
}
vnet_dev_counter_main_t *vnet_dev_counters_alloc (vlib_main_t *,
vnet_dev_counter_t *, u16,
char *, ...);
void vnet_dev_counters_clear (vlib_main_t *, vnet_dev_counter_main_t *);
void vnet_dev_counters_free (vlib_main_t *, vnet_dev_counter_main_t *);
format_function_t format_vnet_dev_counters;
format_function_t format_vnet_dev_counters_all;
static_always_inline vnet_dev_counter_main_t *
vnet_dev_counter_get_main (vnet_dev_counter_t *counter)
{
return (vnet_dev_counter_main_t *) ((u8 *) (counter - counter->index) -
STRUCT_OFFSET_OF (
vnet_dev_counter_main_t, counters));
}
static_always_inline void
vnet_dev_counter_value_add (vlib_main_t *vm, vnet_dev_counter_t *counter,
u64 val)
{
vnet_dev_counter_main_t *cm = vnet_dev_counter_get_main (counter);
cm->counter_data[counter->index] += val;
}
static_always_inline void
vnet_dev_counter_value_update (vlib_main_t *vm, vnet_dev_counter_t *counter,
u64 val)
{
vnet_dev_counter_main_t *cm = vnet_dev_counter_get_main (counter);
cm->counter_data[counter->index] = val - cm->counter_start[counter->index];
}
#define foreach_vnet_dev_counter(c, cm) \
if (cm) \
for (typeof (*(cm)->counters) *(c) = (cm)->counters; \
(c) < (cm)->counters + (cm)->n_counters; (c)++)
#endif /* _VNET_DEV_COUNTERS_H_ */
|