FD.io VPP  v21.01.1
Vector Packet Processing
node_init.c
Go to the documentation of this file.
1 /*
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 #include <vnet/vnet.h>
44 
45 typedef struct _vlib_node_march_variant
46 {
47  struct _vlib_node_march_variant *next_variant;
48  char *name;
50 
51 #define VLIB_VARIANT_REGISTER() \
52  static vlib_node_march_variant_t \
53  CLIB_MARCH_VARIANT##variant; \
54  \
55  static void __clib_constructor \
56  CLIB_MARCH_VARIANT##_register (void) \
57  { \
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; \
63  variants = v; \
64  } \
65 
67 
68 #ifndef CLIB_MARCH_VARIANT
69 
71 
72 uword
74 {
75  u8 **variant = va_arg (*args, u8 **);
77 
78  if (!unformat (input, "%v", variant))
79  return 0;
80 
81  while (v)
82  {
83  if (!strncmp (v->name, (char *) *variant, vec_len (*variant)))
84  return 1;
85 
86  v = v->next_variant;
87  }
88 
89  return 0;
90 }
91 
94  u8 * variant)
95 {
96  vlib_node_fn_registration_t *p_reg = 0;
97  vlib_node_fn_registration_t *v_reg = 0;
98  u32 tmp;
99 
100  while (fnr)
101  {
102  /* which is the highest priority registration */
103  if (!p_reg || fnr->priority > p_reg->priority)
104  p_reg = fnr;
105 
106  /* which is the variant we want to prioritize */
107  if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1))
108  v_reg = fnr;
109 
110  fnr = fnr->next_registration;
111  }
112 
113  /* node doesn't have the variants */
114  if (!v_reg)
115  return;
116 
117  ASSERT (p_reg != 0 && v_reg != 0);
118 
119  /* swap priorities */
120  tmp = p_reg->priority;
121  p_reg->priority = v_reg->priority;
122  v_reg->priority = tmp;
123 
124 }
125 
126 static clib_error_t *
128 {
129  clib_error_t *error = 0;
130  vlib_node_registration_t *nr, **all;
132  vnet_main_t *vnm = vnet_get_main ();
133  unformat_input_t sub_input;
134  uword *hash = 0, *p;
135  u8 *variant = 0;
136  u8 *s = 0;
137 
138  all = 0;
139  hash = hash_create_string (0, sizeof (uword));
140 
141  nr = vm->node_main.node_registrations;
142  while (nr)
143  {
144  hash_set_mem (hash, nr->name, vec_len (all));
145  vec_add1 (all, nr);
146 
147  nr = nr->next_registration;
148  }
149 
150  /* specify prioritization defaults for all graph nodes */
152  {
153  if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
154  &sub_input))
155  {
156  while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
157  {
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);
163 
164  nr = vm->node_main.node_registrations;
165  while (nr)
166  {
167  vlib_update_nr_variant_default (nr->node_fn_registrations,
168  variant);
169  nr = nr->next_registration;
170  }
171 
172  /* also apply it to interfaces */
174  while (c)
175  {
176  vlib_update_nr_variant_default (c->tx_fn_registrations,
177  variant);
178  c = c->next_class_registration;
179  }
180 
181  vec_free (variant);
182  }
183  }
184  else /* specify prioritization for an individual graph node */
185  if (unformat (input, "%s", &s))
186  {
187  if (!(p = hash_get_mem (hash, s)))
188  {
189  error = clib_error_return (0,
190  "node variants: unknown graph node '%s'",
191  s);
192  break;
193  }
194 
195  nr = vec_elt (all, p[0]);
196 
197  if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input))
198  {
199  while (unformat_check_input (&sub_input) !=
201  {
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);
207 
208  vlib_update_nr_variant_default (nr->node_fn_registrations,
209  variant);
210 
211  vec_free (variant);
212  }
213  }
214  }
215  else
216  {
217  break;
218  }
219  }
220 
221  hash_free (hash);
222  vec_free (all);
223  unformat_free (input);
224 
225  return error;
226 }
227 
229 
230 #endif
231 
232 /*
233  * fd.io coding-style-patch-verification: ON
234  *
235  * Local Variables:
236  * eval: (c-set-style "gnu")
237  * End:
238  */
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vnet_device_class_t * device_class_registrations
Definition: vnet.h:68
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
#define hash_set_mem(h, key, value)
Definition: hash.h:275
vlib_main_t * vm
Definition: in2out_ed.c:1580
struct _vnet_device_class vnet_device_class_t
unsigned char u8
Definition: types.h:56
#define static_always_inline
Definition: clib.h:109
struct _vlib_node_march_variant vlib_node_march_variant_t
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_node_march_variant_t * variants
Definition: node_init.c:70
struct _vlib_node_fn_registration vlib_node_fn_registration_t
unsigned int u32
Definition: types.h:88
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
Definition: cJSON.c:84
struct _unformat_input_t unformat_input_t
vlib_node_registration_t * node_registrations
Definition: node.h:747
#define hash_free(h)
Definition: hash.h:310
static_always_inline void vlib_update_nr_variant_default(vlib_node_fn_registration_t *fnr, u8 *variant)
Definition: node_init.c:93
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:226
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define VLIB_VARIANT_REGISTER()
Definition: node_init.c:51
string name[64]
Definition: ip.api:44
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:163
#define ASSERT(truth)
#define vec_elt(v, i)
Get vector value at index i.
struct _vlib_node_registration vlib_node_registration_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_node_main_t node_main
Definition: main.h:188
static clib_error_t * vlib_early_node_config(vlib_main_t *vm, unformat_input_t *input)
Definition: node_init.c:127
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
uword unformat_vlib_node_variant(unformat_input_t *input, va_list *args)
Definition: node_init.c:73
#define hash_get_mem(h, key)
Definition: hash.h:269
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170