tcp: fix cc algo name parsing
[vpp.git] / src / plugins / hs_apps / sapi / echo_common.c
1 /*
2  * Copyright (c) 2019 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
16 #include <stdio.h>
17 #include <signal.h>
18
19 #include <vnet/session/application_interface.h>
20
21 typedef struct
22 {
23   /* VNET_API_ERROR_FOO -> "Foo" hash table */
24   uword *error_string_by_error_number;
25 } echo_common_main_t;
26
27 echo_common_main_t echo_common_main;
28
29 u8 *
30 format_ip4_address (u8 * s, va_list * args)
31 {
32   u8 *a = va_arg (*args, u8 *);
33   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
34 }
35
36 u8 *
37 format_ip6_address (u8 * s, va_list * args)
38 {
39   ip6_address_t *a = va_arg (*args, ip6_address_t *);
40   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
41
42   i_max_n_zero = ARRAY_LEN (a->as_u16);
43   max_n_zeros = 0;
44   i_first_zero = i_max_n_zero;
45   n_zeros = 0;
46   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
47     {
48       u32 is_zero = a->as_u16[i] == 0;
49       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
50         {
51           i_first_zero = i;
52           n_zeros = 0;
53         }
54       n_zeros += is_zero;
55       if ((!is_zero && n_zeros > max_n_zeros)
56           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
57         {
58           i_max_n_zero = i_first_zero;
59           max_n_zeros = n_zeros;
60           i_first_zero = ARRAY_LEN (a->as_u16);
61           n_zeros = 0;
62         }
63     }
64
65   last_double_colon = 0;
66   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
67     {
68       if (i == i_max_n_zero && max_n_zeros > 1)
69         {
70           s = format (s, "::");
71           i += max_n_zeros - 1;
72           last_double_colon = 1;
73         }
74       else
75         {
76           s = format (s, "%s%x",
77                       (last_double_colon || i == 0) ? "" : ":",
78                       clib_net_to_host_u16 (a->as_u16[i]));
79           last_double_colon = 0;
80         }
81     }
82
83   return s;
84 }
85
86 /* Format an IP46 address. */
87 u8 *
88 format_ip46_address (u8 * s, va_list * args)
89 {
90   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
91   ip46_type_t type = va_arg (*args, ip46_type_t);
92   int is_ip4 = 1;
93
94   switch (type)
95     {
96     case IP46_TYPE_ANY:
97       is_ip4 = ip46_address_is_ip4 (ip46);
98       break;
99     case IP46_TYPE_IP4:
100       is_ip4 = 1;
101       break;
102     case IP46_TYPE_IP6:
103       is_ip4 = 0;
104       break;
105     }
106
107   return is_ip4 ?
108     format (s, "%U", format_ip4_address, &ip46->ip4) :
109     format (s, "%U", format_ip6_address, &ip46->ip6);
110 }
111
112 static uword
113 unformat_data (unformat_input_t * input, va_list * args)
114 {
115   u64 _a;
116   u64 *a = va_arg (*args, u64 *);
117   if (unformat (input, "%lluGb", &_a))
118     *a = _a << 30;
119   else if (unformat (input, "%lluMb", &_a))
120     *a = _a << 20;
121   else if (unformat (input, "%lluKb", &_a))
122     *a = _a << 10;
123   else if (unformat (input, "%llu", a))
124     ;
125   else
126     return 0;
127   return 1;
128 }
129
130 static u8 *
131 format_api_error (u8 * s, va_list * args)
132 {
133   echo_common_main_t *ecm = &echo_common_main;
134   i32 error = va_arg (*args, u32);
135   uword *p;
136
137   p = hash_get (ecm->error_string_by_error_number, -error);
138
139   if (p)
140     s = format (s, "%s", p[0]);
141   else
142     s = format (s, "%d", error);
143   return s;
144 }
145
146 static void
147 init_error_string_table ()
148 {
149   echo_common_main_t *ecm = &echo_common_main;
150   ecm->error_string_by_error_number = hash_create (0, sizeof (uword));
151
152 #define _(n,v,s) hash_set (ecm->error_string_by_error_number, -v, s);
153   foreach_vnet_api_error;
154 #undef _
155
156   hash_set (ecm->error_string_by_error_number, 99, "Misc");
157 }
158