blob: 47d288c6ef0cfaa804ef9d0a121b9548c6d96655 [file] [log] [blame]
Ray Kinsella4830e4f2020-03-10 14:35:32 +00001/*
2 * Copyright (c) 2020 Intel 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 * node_init.c: node march variant startup initialization
17 *
18 * Copyright (c) 2020 Intel Corporation
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39
40#include <sys/types.h>
41#include <fcntl.h>
42#include <vlib/vlib.h>
43
44typedef struct _vlib_node_march_variant
45{
46 struct _vlib_node_march_variant *next_variant;
47 char *name;
48} vlib_node_march_variant_t;
49
50#define VLIB_VARIANT_REGISTER() \
51 static vlib_node_march_variant_t \
52 CLIB_MARCH_VARIANT##variant; \
53 \
54 static void __clib_constructor \
55 CLIB_MARCH_VARIANT##_register (void) \
56 { \
57 extern vlib_node_march_variant_t *variants; \
58 vlib_node_march_variant_t *v; \
59 v = & CLIB_MARCH_VARIANT##variant; \
60 v->name = CLIB_MARCH_VARIANT_STR; \
61 v->next_variant = variants; \
62 variants = v; \
63 } \
64
65VLIB_VARIANT_REGISTER ();
66
67#ifndef CLIB_MARCH_VARIANT
68
69vlib_node_march_variant_t *variants = 0;
70
71uword
72unformat_vlib_node_variant (unformat_input_t * input, va_list * args)
73{
74 u8 **variant = va_arg (*args, u8 **);
75 vlib_node_march_variant_t *v = variants;
76
77 if (!unformat (input, "%v", variant))
78 return 0;
79
80 while (v)
81 {
82 if (!strncmp (v->name, (char *) *variant, vec_len (*variant)))
83 return 1;
84
85 v = v->next_variant;
86 }
87
88 return 0;
89}
90
91static_always_inline void
92vlib_update_nr_variant_default (vlib_node_registration_t * nr, u8 * variant)
93{
94 vlib_node_fn_registration_t *fnr = nr->node_fn_registrations;
95 vlib_node_fn_registration_t *p_reg = 0;
96 vlib_node_fn_registration_t *v_reg = 0;
97 u32 tmp;
98
99 while (fnr)
100 {
101 /* which is the highest priority registration */
102 if (!p_reg || fnr->priority > p_reg->priority)
103 p_reg = fnr;
104
105 /* which is the variant we want to prioritize */
106 if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
107 v_reg = fnr;
108
109 fnr = fnr->next_registration;
110 }
111
112 /* node doesn't have the variants */
113 if (!v_reg)
114 return;
115
116 ASSERT (p_reg != 0 && v_reg != 0);
117
118 /* swap priorities */
119 tmp = p_reg->priority;
120 p_reg->priority = v_reg->priority;
121 v_reg->priority = tmp;
122
123}
124
125static clib_error_t *
126vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
127{
128 clib_error_t *error = 0;
129 vlib_node_registration_t *nr, **all;
130 unformat_input_t sub_input;
131 uword *hash = 0, *p;
132 u8 *variant = 0;
133 u8 *s = 0;
134
135 all = 0;
136 hash = hash_create_string (0, sizeof (uword));
137
138 nr = vm->node_main.node_registrations;
139 while (nr)
140 {
141 hash_set_mem (hash, nr->name, vec_len (all));
142 vec_add1 (all, nr);
143
144 nr = nr->next_registration;
145 }
146
147 /* specify prioritization defaults for all graph nodes */
148 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
149 {
150 if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
151 &sub_input))
152 {
153 while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
154 {
155 if (!unformat (&sub_input, "variant %U",
156 unformat_vlib_node_variant, &variant))
157 return clib_error_return (0,
158 "please specify a valid node variant");
159 vec_add1 (variant, 0);
160
161 nr = vm->node_main.node_registrations;
162 while (nr)
163 {
164 vlib_update_nr_variant_default (nr, variant);
165 nr = nr->next_registration;
166 }
167
168 vec_free (variant);
169 }
170 }
171 else /* specify prioritization for an individual graph node */
172 if (unformat (input, "%s", &s))
173 {
174 if (!(p = hash_get_mem (hash, s)))
175 {
176 error = clib_error_return (0,
177 "node variants: unknown graph node '%s'",
178 s);
179 break;
180 }
181
182 nr = vec_elt (all, p[0]);
183
184 if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
185 {
186 while (unformat_check_input (&sub_input) !=
187 UNFORMAT_END_OF_INPUT)
188 {
189 if (!unformat (&sub_input, "variant %U",
190 unformat_vlib_node_variant, &variant))
191 return clib_error_return (0,
192 "please specify a valid node variant");
193 vec_add1 (variant, 0);
194
195 vlib_update_nr_variant_default (nr, variant);
196
197 vec_free (variant);
198 }
199 }
200 }
201 else
202 {
203 break;
204 }
205 }
206
207 hash_free (hash);
208 vec_free (all);
209 unformat_free (input);
210
211 return error;
212}
213
214VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node");
215
216#endif
217
218/*
219 * fd.io coding-style-patch-verification: ON
220 *
221 * Local Variables:
222 * eval: (c-set-style "gnu")
223 * End:
224 */