In-band OAM active probe (VPP-471)
[vpp.git] / src / plugins / ioam / lib-trace / trace_util.h
1 /*
2  * trace_util.h -- Trace Profile Utility header
3  *
4  * Copyright (c) 2016 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef include_vnet_trace_util_h
19 #define include_vnet_trace_util_h
20
21 #define debug_ioam debug_ioam_fn
22
23
24 /**
25  * Usage:
26  *
27  * On any node that participates in iOAM Trace.
28  *
29  * Step 1: Initialize this library by calling trace_init()
30  * Step 2: Setup a trace  profile that contains all the parameters needed to compute cumulative:
31  *         Call these functions:
32  *         trace_profile_find
33  *         trace_profile_create
34  * Step 2a: On initial node enable the profile to be used:
35  *          trace_profile_set_active / trace_profile_get_active will return the profile
36  * Step 4: TBD
37  *         trace_validate
38  *
39  */
40
41 typedef struct trace_profile_
42 {
43   u8 valid:1;
44   u8 trace_type;
45   u8 num_elts;
46   /* Configured node-id */
47   u32 node_id;
48   u32 app_data;
49   u32 trace_tsp;
50 } trace_profile;
51
52 typedef struct
53 {
54   /* Name of the default profile list in use */
55   trace_profile profile;
56
57   /* API message ID base */
58   u16 msg_id_base;
59
60   /* convenience */
61   vlib_main_t *vlib_main;
62   vnet_main_t *vnet_main;
63 } trace_main_t;
64
65 extern trace_main_t trace_main;
66
67 /*
68  * Initialize Trace profile
69  */
70 int trace_util_init (void);
71
72
73 /*
74  * Find a trace profile
75  */
76
77 always_inline trace_profile *
78 trace_profile_find (void)
79 {
80   trace_main_t *sm = &trace_main;
81
82   return (&(sm->profile));
83 }
84
85
86 /* setup and clean up profile */
87 int trace_profile_create (trace_profile * profile, u8 trace_type, u8 num_elts,
88                           u32 trace_tsp, u32 node_id, u32 app_data);
89
90 void clear_trace_profiles (void);
91
92 /* *INDENT-OFF* */
93 typedef CLIB_PACKED (struct
94 {
95   u8 ioam_trace_type;
96   u8 data_list_elts_left;
97   u32 elts[0];  /* Variable type. So keep it generic */
98 }) ioam_trace_hdr_t;
99 /* *INDENT-ON* */
100
101 #define    BIT_TTL_NODEID       (1<<0)
102 #define    BIT_ING_INTERFACE    (1<<1)
103 #define    BIT_EGR_INTERFACE    (1<<2)
104 #define    BIT_TIMESTAMP        (1<<3)
105 #define    BIT_APPDATA          (1<<4)
106 #define    BIT_LOOPBACK         (1<<5)
107 #define    BIT_LOOPBACK_REPLY   (1<<6)
108 #define    TRACE_TYPE_MASK      0x7F    /* Mask of all above bits */
109
110 #define    TRACE_TYPE_IF_TS_APP_LOOP    0x3F
111
112 /*
113      0x00011111  iOAM-trace-type is 0x00011111 then the format of node
114         data is:
115
116           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
117          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118          |   Hop_Lim     |              node_id                          |
119          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120          |     ingress_if_id             |         egress_if_id          |
121          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122          +                           timestamp                           +
123          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124          |                            app_data                           |
125          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126
127 */
128 #define   TRACE_TYPE_IF_TS_APP   0x1f
129 typedef struct
130 {
131   u32 ttl_node_id;
132   u16 ingress_if;
133   u16 egress_if;
134   u32 timestamp;
135   u32 app_data;
136 } ioam_trace_if_ts_app_t;
137
138 /*
139      0x00000111  iOAM-trace-type is 0x00000111 then the format is:
140
141           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
142          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143          |   Hop_Lim     |              node_id                          |
144          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145          |     ingress_if_id             |         egress_if_id          |
146          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147
148 */
149
150 #define   TRACE_TYPE_IF   0x03
151 typedef struct
152 {
153   u32 ttl_node_id;
154   u16 ingress_if;
155   u16 egress_if;
156 } ioam_trace_if_t;
157
158 /*
159      0x00001001  iOAM-trace-type is 0x00001001 then the format is:
160
161           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
162          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163          |   Hop_Lim     |              node_id                          |
164          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165          +                           timestamp                           +
166          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167
168 */
169
170 #define   TRACE_TYPE_TS   0x09
171 typedef struct
172 {
173   u32 ttl_node_id;
174   u32 timestamp;
175 } ioam_trace_ts_t;
176
177 /*
178      0x00010001  iOAM-trace-type is 0x00010001 then the format is:
179
180
181           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
182          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183          |   Hop_Lim     |              node_id                          |
184          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
185          |                            app_data                           |
186          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187
188 */
189
190
191 #define   TRACE_TYPE_APP   0x11
192 typedef struct
193 {
194   u32 ttl_node_id;
195   u32 app_data;
196 } ioam_trace_app_t;
197
198 /*
199
200      0x00011001  iOAM-trace-type is 0x00011001 then the format is:
201
202           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
203          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204          |   Hop_Lim     |              node_id                          |
205          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
206          +                           timestamp                           +
207          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208          |                            app_data                           |
209          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210 */
211
212 #define   TRACE_TYPE_TS_APP   0x19
213 typedef struct
214 {
215   u32 ttl_node_id;
216   u32 timestamp;
217   u32 app_data;
218 } ioam_trace_ts_app_t;
219
220 static inline u8
221 fetch_trace_data_size (u8 trace_type)
222 {
223   u8 trace_data_size = 0;
224
225   if ((trace_type & TRACE_TYPE_IF_TS_APP) == TRACE_TYPE_IF_TS_APP)
226     trace_data_size = sizeof (ioam_trace_if_ts_app_t);
227   else if ((trace_type & TRACE_TYPE_IF) == TRACE_TYPE_IF)
228     trace_data_size = sizeof (ioam_trace_if_t);
229   else if ((trace_type & TRACE_TYPE_TS) == TRACE_TYPE_TS)
230     trace_data_size = sizeof (ioam_trace_ts_t);
231   else if ((trace_type & TRACE_TYPE_APP) == TRACE_TYPE_APP)
232     trace_data_size = sizeof (ioam_trace_app_t);
233   else if ((trace_type & TRACE_TYPE_TS_APP) == TRACE_TYPE_TS_APP)
234     trace_data_size = sizeof (ioam_trace_ts_app_t);
235
236   return trace_data_size;
237 }
238
239 always_inline void
240 ioam_trace_set_bit (ioam_trace_hdr_t * trace_hdr, u8 trace_bit)
241 {
242   trace_hdr->ioam_trace_type |= trace_bit;
243 }
244
245 always_inline void
246 ioam_trace_reset_bit (ioam_trace_hdr_t * trace_hdr, u8 trace_bit)
247 {
248   trace_hdr->ioam_trace_type &= (~trace_bit);
249 }
250
251 int ioam_trace_get_sizeof_handler (u32 * result);
252 int ip6_trace_profile_setup (void);
253 int ip6_trace_profile_cleanup (void);
254
255 #define TSP_SECONDS              0
256 #define TSP_MILLISECONDS         1
257 #define TSP_MICROSECONDS         2
258 #define TSP_NANOSECONDS          3
259
260 #endif
261
262 /*
263  * fd.io coding-style-patch-verification: ON
264  *
265  * Local Variables:
266  * eval: (c-set-style "gnu")
267  * End:
268  */