Move iOAM Trace as a plugin
[vpp.git] / plugins / ioam-plugin / 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 #include <vnet/ip/ip6_hop_by_hop.h>
22 #define debug_ioam debug_ioam_fn
23
24
25 /**
26  * Usage:
27  *
28  * On any node that participates in iOAM Trace.
29  *
30  * Step 1: Initialize this library by calling trace_init()
31  * Step 2: Setup a trace  profile that contains all the parameters needed to compute cumulative:
32  *         Call these functions:
33  *         trace_profile_find
34  *         trace_profile_create
35  * Step 2a: On initial node enable the profile to be used:
36  *          trace_profile_set_active / trace_profile_get_active will return the profile
37  * Step 4: TBD
38  *         trace_validate
39  *
40  */
41
42 typedef struct trace_profile_
43 {
44   u8 valid:1;
45   u8 trace_type;
46   u8 num_elts;
47   /* Configured node-id */
48   u32 node_id;
49   u32 app_data;
50   u32 trace_tsp;
51 } trace_profile;
52
53 typedef struct
54 {
55   /* Name of the default profile list in use */
56   trace_profile profile;
57
58   /* API message ID base */
59   u16 msg_id_base;
60
61   /* convenience */
62   vlib_main_t *vlib_main;
63   vnet_main_t *vnet_main;
64 } trace_main_t;
65
66 extern trace_main_t trace_main;
67
68 /*
69  * Initialize Trace profile
70  */
71 int trace_util_init (void);
72
73
74 /*
75  * Find a trace profile by ID
76  */
77 always_inline trace_profile *trace_profile_find (void);
78
79 always_inline trace_profile *
80 trace_profile_find (void)
81 {
82   trace_main_t *sm = &trace_main;
83
84   return (&(sm->profile));
85 }
86
87
88 /* setup and clean up profile */
89 int trace_profile_create (trace_profile * profile, u8 trace_type, u8 num_elts,
90                           u32 trace_tsp, u32 node_id, u32 app_data);
91
92 void clear_trace_profiles (void);
93
94
95
96 #define    BIT_TTL_NODEID       (1<<0)
97 #define    BIT_ING_INTERFACE    (1<<1)
98 #define    BIT_EGR_INTERFACE    (1<<2)
99 #define    BIT_TIMESTAMP        (1<<3)
100 #define    BIT_APPDATA          (1<<4)
101 #define    TRACE_TYPE_MASK      0x1F    /* Mask of all above bits */
102
103 /*
104      0x00011111  iOAM-trace-type is 0x00011111 then the format of node
105         data is:
106
107           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
108          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109          |   Hop_Lim     |              node_id                          |
110          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111          |     ingress_if_id             |         egress_if_id          |
112          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113          +                           timestamp                           +
114          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115          |                            app_data                           |
116          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117
118 */
119 #define   TRACE_TYPE_IF_TS_APP   0x1f
120 typedef struct
121 {
122   u32 ttl_node_id;
123   u16 ingress_if;
124   u16 egress_if;
125   u32 timestamp;
126   u32 app_data;
127 } ioam_trace_if_ts_app_t;
128
129 /*
130      0x00000111  iOAM-trace-type is 0x00000111 then the format is:
131
132           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
133          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134          |   Hop_Lim     |              node_id                          |
135          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136          |     ingress_if_id             |         egress_if_id          |
137          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138
139 */
140
141 #define   TRACE_TYPE_IF   0x03
142 typedef struct
143 {
144   u32 ttl_node_id;
145   u16 ingress_if;
146   u16 egress_if;
147 } ioam_trace_if_t;
148
149 /*
150      0x00001001  iOAM-trace-type is 0x00001001 then the format is:
151
152           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
153          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154          |   Hop_Lim     |              node_id                          |
155          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156          +                           timestamp                           +
157          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158
159 */
160
161 #define   TRACE_TYPE_TS   0x09
162 typedef struct
163 {
164   u32 ttl_node_id;
165   u32 timestamp;
166 } ioam_trace_ts_t;
167
168 /*
169      0x00010001  iOAM-trace-type is 0x00010001 then the format is:
170
171
172           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
173          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174          |   Hop_Lim     |              node_id                          |
175          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
176          |                            app_data                           |
177          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178
179 */
180
181
182 #define   TRACE_TYPE_APP   0x11
183 typedef struct
184 {
185   u32 ttl_node_id;
186   u32 app_data;
187 } ioam_trace_app_t;
188
189 /*
190
191      0x00011001  iOAM-trace-type is 0x00011001 then the format is:
192
193           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
194          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
195          |   Hop_Lim     |              node_id                          |
196          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
197          +                           timestamp                           +
198          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199          |                            app_data                           |
200          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201 */
202
203 #define   TRACE_TYPE_TS_APP   0x19
204 typedef struct
205 {
206   u32 ttl_node_id;
207   u32 timestamp;
208   u32 app_data;
209 } ioam_trace_ts_app_t;
210
211
212 /* *INDENT-OFF* */
213 typedef CLIB_PACKED(struct {
214   ip6_hop_by_hop_option_t hdr;
215   u8 ioam_trace_type;
216   u8 data_list_elts_left;
217   u32 elts[0]; /* Variable type. So keep it generic */
218 }) ioam_trace_option_t;
219 /* *INDENT-ON* */
220
221
222 static inline u8
223 fetch_trace_data_size (u8 trace_type)
224 {
225   u8 trace_data_size = 0;
226
227   if (trace_type == TRACE_TYPE_IF_TS_APP)
228     trace_data_size = sizeof (ioam_trace_if_ts_app_t);
229   else if (trace_type == TRACE_TYPE_IF)
230     trace_data_size = sizeof (ioam_trace_if_t);
231   else if (trace_type == TRACE_TYPE_TS)
232     trace_data_size = sizeof (ioam_trace_ts_t);
233   else if (trace_type == TRACE_TYPE_APP)
234     trace_data_size = sizeof (ioam_trace_app_t);
235   else if (trace_type == TRACE_TYPE_TS_APP)
236     trace_data_size = sizeof (ioam_trace_ts_app_t);
237
238   return trace_data_size;
239 }
240
241 int ioam_trace_get_sizeof_handler (u32 * result);
242 #endif
243
244 /*
245  * fd.io coding-style-patch-verification: ON
246  *
247  * Local Variables:
248  * eval: (c-set-style "gnu")
249  * End:
250  */