summaryrefslogtreecommitdiffstats
path: root/src/vnet/dev/counters.h
blob: 33d08ffbecd8219fcaa1d1fdf519fac31f0b95eb (plain)
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
/* 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,
} __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_ */