FD.io VPP  v20.05-21-gb1500e9ff
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 
44 typedef struct _vlib_node_march_variant
45 {
46  struct _vlib_node_march_variant *next_variant;
47  char *name;
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 
66 
67 #ifndef CLIB_MARCH_VARIANT
68 
70 
71 uword
73 {
74  u8 **variant = va_arg (*args, u8 **);
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 
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 
125 static clib_error_t *
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 */
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) !=
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 
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  */
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:590
#define hash_set_mem(h, key, value)
Definition: hash.h:275
unsigned char u8
Definition: types.h:56
#define static_always_inline
Definition: clib.h:106
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:69
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
static_always_inline void vlib_update_nr_variant_default(vlib_node_registration_t *nr, u8 *variant)
Definition: node_init.c:92
struct _unformat_input_t unformat_input_t
vlib_node_registration_t * node_registrations
Definition: node.h:766
#define hash_free(h)
Definition: hash.h:310
vlib_main_t * vm
Definition: in2out_ed.c:1599
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:226
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define VLIB_VARIANT_REGISTER()
Definition: node_init.c:50
string name[64]
Definition: ip.api:44
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:162
#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:158
static clib_error_t * vlib_early_node_config(vlib_main_t *vm, unformat_input_t *input)
Definition: node_init.c:126
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
uword unformat_vlib_node_variant(unformat_input_t *input, va_list *args)
Definition: node_init.c:72
#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:171