4bc9f84deecfa899707fb6bf05268ff7a19d685e
[vpp.git] / plugins / ioam-plugin / ioam / lib-trace / trace_util.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/vnet.h>
16 #include <stdint.h>
17 #include <time.h>
18 #include <string.h>
19 #include <vppinfra/mem.h>
20 #include "trace_util.h"
21
22 trace_main_t trace_main;
23
24 extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
25
26 static int
27 trace_profile_cleanup (trace_profile * profile)
28 {
29   int rv;
30   ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
31
32   memset (profile, 0, sizeof (trace_profile));
33   profile->trace_tsp = TSP_MICROSECONDS;        /* Micro seconds */
34   hm->options_size[HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST] = 0;
35   if (0 !=
36       (rv =
37        ip6_ioam_set_rewrite (&hm->rewrite, hm->has_trace_option,
38                              hm->has_pot_option, hm->has_ppc_option)))
39     return (-1);
40   return 0;
41
42 }
43
44 static int
45 trace_main_profiles_reset (void)
46 {
47   int rv;
48
49   trace_main_t *sm = &trace_main;
50   rv = trace_profile_cleanup (&(sm->profile));
51   return (rv);
52 }
53
54 int
55 trace_util_init (void)
56 {
57   int rv;
58
59   rv = trace_main_profiles_reset ();
60   return (rv);
61 }
62
63
64 int
65 trace_profile_create (trace_profile * profile, u8 trace_type, u8 num_elts,
66                       u32 trace_tsp, u32 node_id, u32 app_data)
67 {
68   u32 trace_size = 0;
69   int rv;
70   ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
71
72   if (profile && !profile->valid)
73     {
74       //rv = trace_profile_cleanup (profile);
75       profile->trace_type = trace_type;
76       profile->num_elts = num_elts;
77       profile->trace_tsp = trace_tsp;
78       profile->node_id = node_id;
79       profile->app_data = app_data;
80       profile->valid = 1;
81
82       if (ioam_trace_get_sizeof_handler (&trace_size) < 0)
83         return (-1);
84
85       hm->options_size[HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST] = trace_size;
86
87       if (hm->has_trace_option)
88         {
89           if (0 !=
90               (rv =
91                ip6_ioam_set_rewrite (&hm->rewrite, hm->has_trace_option,
92                                      hm->has_pot_option, hm->has_ppc_option)))
93             return (-1);
94
95         }
96       return (0);
97     }
98
99   return (-1);
100 }
101
102
103
104 clib_error_t *
105 clear_trace_profile_command_fn (vlib_main_t * vm,
106                                 unformat_input_t * input,
107                                 vlib_cli_command_t * cmd)
108 {
109
110   trace_main_profiles_reset ();
111   return 0;
112 }
113
114 void
115 clear_trace_profiles (void)
116 {
117   clear_trace_profile_command_fn (0, 0, 0);
118 }
119
120 /* *INDENT-OFF* */
121 VLIB_CLI_COMMAND(clear_trace_profile_command) =
122 {
123 .path = "clear ioam-trace profile",
124 .short_help = "clear ioam-trace profile [<index>|all]",
125 .function = clear_trace_profile_command_fn,
126 };
127 /* *INDENT-ON* */
128
129 static clib_error_t *
130 set_trace_profile_command_fn (vlib_main_t * vm,
131                               unformat_input_t * input,
132                               vlib_cli_command_t * cmd)
133 {
134   u8 trace_type = 0;
135   u8 num_elts = 0;
136   u32 node_id = 0;
137   u32 app_data = 0;
138   u32 trace_tsp = 0;
139   trace_profile *profile = NULL;
140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
141     {
142       if (unformat (input, "trace-type 0x%x", &trace_type));
143       else if (unformat (input, "trace-elts %d", &num_elts));
144       else if (unformat (input, "trace-tsp %d", &trace_tsp));
145       else if (unformat (input, "node-id 0x%x", &node_id));
146       else if (unformat (input, "app-data 0x%x", &app_data));
147       else
148         return clib_error_return (0, "unknown input `%U'",
149                                   format_unformat_error, input);
150     }
151   profile = trace_profile_find ();
152   if (profile)
153     {
154       trace_profile_create (profile, trace_type, num_elts, trace_tsp,
155                             node_id, app_data);
156     }
157   return 0;
158 }
159
160 /* *INDENT-OFF* */
161 VLIB_CLI_COMMAND (set_trace_profile_command) =
162 {
163 .path = "set ioam-trace profile",.short_help = "set ioam-trace \
164                   trace-type <0x1f|0x3|0x9|0x11|0x19> trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> app-data <app_data in hex>",.function = set_trace_profile_command_fn,};
165
166 /* *INDENT-ON* */
167
168 static clib_error_t *
169 show_trace_profile_command_fn (vlib_main_t * vm,
170                                unformat_input_t * input,
171                                vlib_cli_command_t * cmd)
172 {
173   trace_profile *p = NULL;
174   u8 *s = 0;
175   p = trace_profile_find ();
176   if (p->valid == 0)
177     return 0;
178   s = format (s, " HOP BY HOP OPTIONS - TRACE CONFIG - \n");
179   s = format (s, "                        Trace Type : 0x%x (%d)\n",
180               p->trace_type, p->trace_type);
181   s =
182     format (s, "         Trace timestamp precision : %d (%s)\n",
183             p->trace_tsp,
184             (p->trace_tsp ==
185              TSP_SECONDS) ? "Seconds" : ((p->trace_tsp ==
186                                           TSP_MILLISECONDS) ?
187                                          "Milliseconds"
188                                          : (((p->trace_tsp ==
189                                               TSP_MICROSECONDS) ?
190                                              "Microseconds" :
191                                              "Nanoseconds"))));
192   s = format (s, "                Num of trace nodes : %d\n", p->num_elts);
193   s =
194     format (s, "                           Node-id : 0x%x (%d)\n",
195             p->node_id, p->node_id);
196   s =
197     format (s, "                          App Data : 0x%x (%d)\n",
198             p->app_data, p->app_data);
199   if (!(p && p->valid))
200     {
201       s = format (s, "\nTrace configuration not valid\n");
202     }
203   vlib_cli_output (vm, "%v", s);
204   vec_free (s);
205   return 0;
206 }
207
208 /* *INDENT-OFF* */
209 VLIB_CLI_COMMAND (show_trace_profile_command) =
210 {
211 .path = "show ioam-trace profile",.short_help =
212     "show ioam-trace profile",.function = show_trace_profile_command_fn,};
213 /* *INDENT-ON* */
214
215 /*
216  * fd.io coding-style-patch-verification: ON
217  *
218  * Local Variables:
219  * eval: (c-set-style "gnu")
220  * End:
221  */