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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * node_init.c: node march variant startup initialization
18 * Copyright (c) 2020 Intel Corporation
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:
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
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.
40 #include <sys/types.h>
42 #include <vlib/vlib.h>
43 #include <vnet/vnet.h>
45 typedef struct _vlib_node_march_variant
47 struct _vlib_node_march_variant *next_variant;
49 } vlib_node_march_variant_t;
51 #define VLIB_VARIANT_REGISTER() \
52 static vlib_node_march_variant_t \
53 CLIB_MARCH_VARIANT##variant; \
55 static void __clib_constructor \
56 CLIB_MARCH_VARIANT##_register (void) \
58 extern vlib_node_march_variant_t *variants; \
59 vlib_node_march_variant_t *v; \
60 v = & CLIB_MARCH_VARIANT##variant; \
61 v->name = CLIB_MARCH_VARIANT_STR; \
62 v->next_variant = variants; \
66 VLIB_VARIANT_REGISTER ();
68 #ifndef CLIB_MARCH_VARIANT
70 vlib_node_march_variant_t *variants = 0;
73 unformat_vlib_node_variant (unformat_input_t * input, va_list * args)
75 u8 **variant = va_arg (*args, u8 **);
76 vlib_node_march_variant_t *v = variants;
78 if (!unformat (input, "%v", variant))
83 if (!strncmp (v->name, (char *) *variant, vec_len (*variant)))
92 static_always_inline void
93 vlib_update_nr_variant_default (vlib_node_fn_registration_t * fnr,
96 vlib_node_fn_registration_t *p_reg = 0;
97 vlib_node_fn_registration_t *v_reg = 0;
102 /* which is the highest priority registration */
103 if (!p_reg || fnr->priority > p_reg->priority)
106 /* which is the variant we want to prioritize */
107 if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
110 fnr = fnr->next_registration;
113 /* node doesn't have the variants */
117 ASSERT (p_reg != 0 && v_reg != 0);
119 /* swap priorities */
120 tmp = p_reg->priority;
121 p_reg->priority = v_reg->priority;
122 v_reg->priority = tmp;
126 static clib_error_t *
127 vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
129 clib_error_t *error = 0;
130 vlib_node_registration_t *nr, **all;
131 vnet_device_class_t *c;
132 vnet_main_t *vnm = vnet_get_main ();
133 unformat_input_t sub_input;
139 hash = hash_create_string (0, sizeof (uword));
141 nr = vm->node_main.node_registrations;
144 hash_set_mem (hash, nr->name, vec_len (all));
147 nr = nr->next_registration;
150 /* specify prioritization defaults for all graph nodes */
151 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
153 if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
156 while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
158 if (!unformat (&sub_input, "variant %U",
159 unformat_vlib_node_variant, &variant))
160 return clib_error_return (0,
161 "please specify a valid node variant");
162 vec_add1 (variant, 0);
164 nr = vm->node_main.node_registrations;
167 vlib_update_nr_variant_default (nr->node_fn_registrations,
169 nr = nr->next_registration;
172 /* also apply it to interfaces */
173 c = vnm->device_class_registrations;
176 vlib_update_nr_variant_default (c->tx_fn_registrations,
178 c = c->next_class_registration;
184 else /* specify prioritization for an individual graph node */
185 if (unformat (input, "%s", &s))
187 if (!(p = hash_get_mem (hash, s)))
189 error = clib_error_return (0,
190 "node variants: unknown graph node '%s'",
195 nr = vec_elt (all, p[0]);
197 if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
199 while (unformat_check_input (&sub_input) !=
200 UNFORMAT_END_OF_INPUT)
202 if (!unformat (&sub_input, "variant %U",
203 unformat_vlib_node_variant, &variant))
204 return clib_error_return (0,
205 "please specify a valid node variant");
206 vec_add1 (variant, 0);
208 vlib_update_nr_variant_default (nr->node_fn_registrations,
223 unformat_free (input);
228 VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node");
233 * fd.io coding-style-patch-verification: ON
236 * eval: (c-set-style "gnu")