Line data Source code
1 : /*
2 : * Copyright (c) 2015 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 : * interface_funcs.h: VNET interfaces/sub-interfaces exported functions
17 : *
18 : * Copyright (c) 2008 Eliot Dresselhaus
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 : #ifndef included_vnet_interface_funcs_h
41 : #define included_vnet_interface_funcs_h
42 :
43 : always_inline vnet_hw_interface_t *
44 57338251 : vnet_get_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
45 : {
46 57338251 : return pool_elt_at_index (vnm->interface_main.hw_interfaces, hw_if_index);
47 : }
48 :
49 : always_inline vnet_hw_interface_t *
50 37 : vnet_get_hw_interface_or_null (vnet_main_t * vnm, u32 hw_if_index)
51 : {
52 37 : if (!pool_is_free_index (vnm->interface_main.hw_interfaces, hw_if_index))
53 37 : return pool_elt_at_index (vnm->interface_main.hw_interfaces, hw_if_index);
54 0 : return (NULL);
55 : }
56 :
57 : always_inline vnet_sw_interface_t *
58 54806316 : vnet_get_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
59 : {
60 54806316 : return pool_elt_at_index (vnm->interface_main.sw_interfaces, sw_if_index);
61 : }
62 :
63 : always_inline vnet_sw_interface_t *
64 503487 : vnet_get_sw_interface_or_null (vnet_main_t * vnm, u32 sw_if_index)
65 : {
66 503487 : if (!pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
67 496810 : return pool_elt_at_index (vnm->interface_main.sw_interfaces, sw_if_index);
68 6677 : return (NULL);
69 : }
70 :
71 : always_inline vnet_sw_interface_t *
72 27513 : vnet_get_hw_sw_interface (vnet_main_t * vnm, u32 hw_if_index)
73 : {
74 27513 : vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
75 27513 : vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, hw->sw_if_index);
76 27513 : ASSERT (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE);
77 27513 : return sw;
78 : }
79 :
80 : always_inline vnet_sw_interface_t *
81 51724849 : vnet_get_sup_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
82 : {
83 51724849 : vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
84 51724849 : if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
85 51709871 : sw->type == VNET_SW_INTERFACE_TYPE_PIPE ||
86 51708323 : sw->type == VNET_SW_INTERFACE_TYPE_P2P)
87 47294 : sw = vnet_get_sw_interface (vnm, sw->sup_sw_if_index);
88 51724849 : return sw;
89 : }
90 :
91 : always_inline vnet_hw_interface_t *
92 50483566 : vnet_get_sup_hw_interface (vnet_main_t * vnm, u32 sw_if_index)
93 : {
94 50483566 : vnet_sw_interface_t *sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
95 50483566 : ASSERT ((sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE) ||
96 : (sw->type == VNET_SW_INTERFACE_TYPE_PIPE));
97 50483566 : return vnet_get_hw_interface (vnm, sw->hw_if_index);
98 : }
99 :
100 : always_inline vnet_hw_interface_t *
101 8982 : vnet_get_sup_hw_interface_api_visible_or_null (vnet_main_t * vnm,
102 : u32 sw_if_index)
103 : {
104 : vnet_sw_interface_t *si;
105 8982 : if (PREDICT_FALSE (pool_is_free_index (vnm->interface_main.sw_interfaces,
106 : sw_if_index)))
107 0 : return NULL;
108 8982 : si = vnet_get_sup_sw_interface (vnm, sw_if_index);
109 8982 : if (PREDICT_FALSE (si->flags & VNET_SW_INTERFACE_FLAG_HIDDEN))
110 0 : return NULL;
111 8982 : ASSERT ((si->type == VNET_SW_INTERFACE_TYPE_HARDWARE) ||
112 : (si->type == VNET_SW_INTERFACE_TYPE_PIPE));
113 8982 : return vnet_get_hw_interface (vnm, si->hw_if_index);
114 : }
115 :
116 : always_inline vnet_hw_interface_class_t *
117 228644 : vnet_get_hw_interface_class (vnet_main_t * vnm, u32 hw_class_index)
118 : {
119 228644 : return vec_elt_at_index (vnm->interface_main.hw_interface_classes,
120 : hw_class_index);
121 : }
122 :
123 : always_inline vnet_device_class_t *
124 99941 : vnet_get_device_class (vnet_main_t * vnm, u32 dev_class_index)
125 : {
126 99941 : return vec_elt_at_index (vnm->interface_main.device_classes,
127 : dev_class_index);
128 : }
129 :
130 : static inline u8 *
131 7007 : vnet_get_sw_interface_tag (vnet_main_t * vnm, u32 sw_if_index)
132 : {
133 : uword *p;
134 7007 : p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index);
135 7007 : if (p)
136 0 : return ((u8 *) p[0]);
137 7007 : return 0;
138 : }
139 :
140 : static inline void
141 0 : vnet_set_sw_interface_tag (vnet_main_t * vnm, u8 * tag, u32 sw_if_index)
142 : {
143 : uword *p;
144 0 : p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index);
145 0 : if (p)
146 : {
147 0 : u8 *oldtag = (u8 *) p[0];
148 0 : hash_unset (vnm->interface_tag_by_sw_if_index, sw_if_index);
149 0 : vec_free (oldtag);
150 : }
151 :
152 0 : hash_set (vnm->interface_tag_by_sw_if_index, sw_if_index, tag);
153 0 : }
154 :
155 : static inline void
156 4627 : vnet_clear_sw_interface_tag (vnet_main_t * vnm, u32 sw_if_index)
157 : {
158 : uword *p;
159 4627 : p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index);
160 4627 : if (p)
161 : {
162 0 : u8 *oldtag = (u8 *) p[0];
163 0 : hash_unset (vnm->interface_tag_by_sw_if_index, sw_if_index);
164 0 : vec_free (oldtag);
165 : }
166 4627 : }
167 :
168 : /**
169 : * Walk return code
170 : */
171 : typedef enum walk_rc_t_
172 : {
173 : WALK_STOP,
174 : WALK_CONTINUE,
175 : } walk_rc_t;
176 :
177 : /**
178 : * Call back walk type for walking SW indices on a HW interface
179 : */
180 : typedef walk_rc_t (*vnet_hw_sw_interface_walk_t) (vnet_main_t * vnm,
181 : u32 sw_if_index, void *ctx);
182 :
183 : /**
184 : * @brief
185 : * Walk the SW interfaces on a HW interface - this is the super
186 : * interface and any sub-interfaces.
187 : */
188 : void vnet_hw_interface_walk_sw (vnet_main_t * vnm,
189 : u32 hw_if_index,
190 : vnet_hw_sw_interface_walk_t fn, void *ctx);
191 :
192 : /**
193 : * Call back walk type for walking SW indices on a HW interface
194 : */
195 : typedef walk_rc_t (*vnet_sw_interface_walk_t) (vnet_main_t * vnm,
196 : vnet_sw_interface_t * si,
197 : void *ctx);
198 :
199 : /**
200 : * @brief
201 : * Walk all the SW interfaces in the system.
202 : */
203 : void vnet_sw_interface_walk (vnet_main_t * vnm,
204 : vnet_sw_interface_walk_t fn, void *ctx);
205 :
206 :
207 : /**
208 : * Call back walk type for walking all HW indices
209 : */
210 : typedef walk_rc_t (*vnet_hw_interface_walk_t) (vnet_main_t * vnm,
211 : u32 hw_if_index, void *ctx);
212 :
213 : /**
214 : * @brief
215 : * Walk all the HW interface
216 : */
217 : void vnet_hw_interface_walk (vnet_main_t * vnm,
218 : vnet_hw_interface_walk_t fn, void *ctx);
219 :
220 : /* Register a hardware interface instance. */
221 : u32 vnet_register_interface (vnet_main_t * vnm,
222 : u32 dev_class_index,
223 : u32 dev_instance,
224 : u32 hw_class_index, u32 hw_instance);
225 :
226 : /**
227 : * Set interface output node - for interface registered without its output/tx
228 : * nodes created because its VNET_DEVICE_CLASS did not specify any tx_function.
229 : * This is typically the case for tunnel interfaces.
230 : */
231 : void vnet_set_interface_output_node (vnet_main_t * vnm,
232 : u32 hw_if_index, u32 node_index);
233 :
234 : void vnet_set_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index,
235 : u8 *output_node);
236 : void vnet_reset_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index);
237 :
238 : /* Creates a software interface given template. */
239 : clib_error_t *vnet_create_sw_interface (vnet_main_t * vnm,
240 : vnet_sw_interface_t * template,
241 : u32 * sw_if_index);
242 :
243 : void vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index);
244 : void vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index);
245 : int vnet_sw_interface_is_p2p (vnet_main_t * vnm, u32 sw_if_index);
246 : int vnet_sw_interface_is_nbma (vnet_main_t * vnm, u32 sw_if_index);
247 :
248 : always_inline vnet_sw_interface_flags_t
249 112270 : vnet_sw_interface_get_flags (vnet_main_t * vnm, u32 sw_if_index)
250 : {
251 112270 : vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
252 112270 : return sw->flags;
253 : }
254 :
255 : always_inline uword
256 4 : vnet_sw_interface_is_valid (vnet_main_t * vnm, u32 sw_if_index)
257 : {
258 4 : return !pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index);
259 : }
260 :
261 : always_inline uword
262 0 : vnet_hw_interface_is_valid (vnet_main_t * vnm, u32 hw_if_index)
263 : {
264 0 : return !pool_is_free_index (vnm->interface_main.hw_interfaces, hw_if_index);
265 : }
266 :
267 :
268 : always_inline uword
269 109746 : vnet_sw_interface_is_admin_up (vnet_main_t * vnm, u32 sw_if_index)
270 : {
271 109746 : return (vnet_sw_interface_get_flags (vnm, sw_if_index) &
272 109746 : VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
273 : }
274 :
275 : always_inline uword
276 62970 : vnet_swif_is_api_visible (vnet_sw_interface_t * si)
277 : {
278 62970 : return !(si->flags & VNET_SW_INTERFACE_FLAG_HIDDEN);
279 : }
280 :
281 : always_inline uword
282 46063 : vnet_sw_interface_is_api_visible (vnet_main_t * vnm, u32 sw_if_index)
283 : {
284 46063 : vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
285 46063 : return vnet_swif_is_api_visible (si);
286 : }
287 :
288 : always_inline uword
289 45875 : vnet_sw_interface_is_api_valid (vnet_main_t * vnm, u32 sw_if_index)
290 : {
291 45875 : return !pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)
292 45875 : && vnet_sw_interface_is_api_visible (vnm, sw_if_index);
293 : }
294 :
295 : always_inline const u8 *
296 13 : vnet_sw_interface_get_hw_address (vnet_main_t * vnm, u32 sw_if_index)
297 : {
298 13 : vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
299 13 : return hw->hw_address;
300 : }
301 :
302 : always_inline uword
303 50006 : vnet_hw_interface_get_flags (vnet_main_t * vnm, u32 hw_if_index)
304 : {
305 50006 : vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
306 50006 : return hw->flags;
307 : }
308 :
309 : always_inline u32
310 : vnet_hw_interface_get_mtu (vnet_main_t * vnm, u32 hw_if_index)
311 : {
312 : vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
313 : return hw->max_frame_size - hw->frame_overhead;
314 : }
315 :
316 : always_inline u32
317 41769 : vnet_sw_interface_get_mtu (vnet_main_t * vnm, u32 sw_if_index, vnet_mtu_t af)
318 : {
319 41769 : vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
320 : u32 mtu;
321 41769 : mtu = sw->mtu[af] > 0 ? sw->mtu[af] : sw->mtu[VNET_MTU_L3];
322 41769 : if (mtu == 0)
323 1022 : return 9000; /* $$$ Deal with interface-types not setting MTU */
324 40747 : return mtu;
325 : }
326 :
327 : always_inline uword
328 49454 : vnet_hw_interface_is_link_up (vnet_main_t * vnm, u32 hw_if_index)
329 : {
330 49454 : return ((vnet_hw_interface_get_flags (vnm, hw_if_index) &
331 49454 : VNET_HW_INTERFACE_FLAG_LINK_UP) != 0);
332 : }
333 :
334 : always_inline uword
335 49450 : vnet_sw_interface_is_link_up (vnet_main_t * vnm, u32 sw_if_index)
336 : {
337 49450 : vnet_sw_interface_t *sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
338 :
339 49450 : return (vnet_hw_interface_is_link_up (vnm, sw->hw_if_index));
340 : }
341 :
342 : always_inline uword
343 53399 : vnet_sw_interface_is_up (vnet_main_t * vnm, u32 sw_if_index)
344 : {
345 102849 : return (vnet_sw_interface_is_admin_up (vnm, sw_if_index) &&
346 49450 : vnet_sw_interface_is_link_up (vnm, sw_if_index));
347 : }
348 :
349 : always_inline uword
350 8972 : vnet_sw_interface_is_sub (vnet_main_t *vnm, u32 sw_if_index)
351 : {
352 8972 : vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
353 :
354 8972 : return (sw->sw_if_index != sw->sup_sw_if_index);
355 : }
356 :
357 : clib_error_t *vnet_sw_interface_supports_addressing (vnet_main_t *vnm,
358 : u32 sw_if_index);
359 :
360 : always_inline vlib_frame_t *
361 4 : vnet_get_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
362 : {
363 4 : vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
364 4 : return vlib_get_frame_to_node (vlib_get_main (), hw->output_node_index);
365 : }
366 :
367 : always_inline void
368 4 : vnet_put_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index,
369 : vlib_frame_t * f)
370 : {
371 4 : vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
372 4 : return vlib_put_frame_to_node (vlib_get_main (), hw->output_node_index, f);
373 : }
374 :
375 : always_inline void
376 0 : vnet_hw_interface_set_link_speed (vnet_main_t * vnm, u32 hw_if_index,
377 : u32 link_speed)
378 : {
379 0 : vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
380 0 : hw->link_speed = link_speed;
381 0 : }
382 :
383 : /* Change interface flags (e.g. up, down, enable, disable). */
384 : clib_error_t *vnet_hw_interface_set_flags (vnet_main_t * vnm, u32 hw_if_index,
385 : vnet_hw_interface_flags_t flags);
386 :
387 : /* Change interface flags (e.g. up, down, enable, disable). */
388 : clib_error_t *vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index,
389 : vnet_sw_interface_flags_t flags);
390 :
391 : void vnet_sw_interface_admin_up (vnet_main_t * vnm, u32 sw_if_index);
392 : void vnet_sw_interface_admin_down (vnet_main_t * vnm, u32 sw_if_index);
393 :
394 : /* Change interface class. */
395 : clib_error_t *vnet_hw_interface_set_class (vnet_main_t * vnm, u32 hw_if_index,
396 : u32 new_hw_class_index);
397 :
398 : /* Redirect rx pkts to node */
399 : int vnet_hw_interface_rx_redirect_to_node (vnet_main_t * vnm, u32 hw_if_index,
400 : u32 node_index);
401 :
402 : void vnet_hw_interface_init_for_class (vnet_main_t * vnm, u32 hw_if_index,
403 : u32 hw_class_index, u32 hw_instance);
404 :
405 : /* Rename interface */
406 : clib_error_t *vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index,
407 : char *new_name);
408 :
409 : /* Add/delete secondary interface mac address*/
410 : clib_error_t *vnet_hw_interface_add_del_mac_address (vnet_main_t * vnm,
411 : u32 hw_if_index,
412 : const u8 * mac_address,
413 : u8 is_add);
414 :
415 : /* Change interface mac address*/
416 : clib_error_t *vnet_hw_interface_change_mac_address (vnet_main_t * vnm,
417 : u32 hw_if_index,
418 : const u8 * mac_address);
419 :
420 : /* Change rx-mode */
421 : clib_error_t *set_hw_interface_change_rx_mode (vnet_main_t * vnm,
422 : u32 hw_if_index,
423 : u8 queue_id_valid,
424 : u32 queue_id,
425 : vnet_hw_if_rx_mode mode);
426 :
427 : /* Set rx-placement on the interface */
428 : clib_error_t *set_hw_interface_rx_placement (u32 hw_if_index, u32 queue_id,
429 : u32 thread_index, u8 is_main);
430 : /* Set tx-queue placement on the interface */
431 : int set_hw_interface_tx_queue (u32 hw_if_index, u32 queue_id, uword *bitmap);
432 :
433 : /* Set the Max Frame Size on the HW interface */
434 : clib_error_t *vnet_hw_interface_set_max_frame_size (vnet_main_t *vnm,
435 : u32 hw_if_index,
436 : u32 max_frame_size);
437 : /* Set the MTU on the HW interface */
438 : clib_error_t *vnet_hw_interface_set_mtu (vnet_main_t *vnm, u32 hw_if_index,
439 : u32 mtu);
440 :
441 : /* Set the MTU on the SW interface */
442 : void vnet_sw_interface_set_mtu (vnet_main_t * vnm, u32 sw_if_index, u32 mtu);
443 : void vnet_sw_interface_set_protocol_mtu (vnet_main_t * vnm, u32 sw_if_index,
444 : u32 mtu[]);
445 :
446 : /* update the unnumbered state of an interface */
447 : int vnet_sw_interface_update_unnumbered (u32 sw_if_index, u32 ip_sw_if_index,
448 : u8 enable);
449 :
450 : int vnet_sw_interface_stats_collect_enable_disable (u32 sw_if_index,
451 : u8 enable);
452 : void vnet_sw_interface_ip_directed_broadcast (vnet_main_t * vnm,
453 : u32 sw_if_index, u8 enable);
454 :
455 : /* set interface rss queues */
456 : clib_error_t *vnet_hw_interface_set_rss_queues (vnet_main_t * vnm,
457 : vnet_hw_interface_t * hi,
458 : clib_bitmap_t * bitmap);
459 :
460 : void vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index);
461 :
462 : /* Formats sw/hw interface. */
463 : format_function_t format_vnet_hw_interface;
464 : format_function_t format_vnet_hw_if_rx_mode;
465 : format_function_t format_vnet_hw_if_index_name;
466 : format_function_t format_vnet_sw_interface;
467 : format_function_t format_vnet_sw_interface_name;
468 : format_function_t format_vnet_sw_interface_name_override;
469 : format_function_t format_vnet_sw_if_index_name;
470 : format_function_t format_vnet_sw_interface_flags;
471 :
472 : /* Parses sw/hw interface name -> index. */
473 : unformat_function_t unformat_vnet_sw_interface;
474 : unformat_function_t unformat_vnet_hw_interface;
475 : unformat_function_t unformat_vnet_buffer_flags;
476 : unformat_function_t unformat_vnet_buffer_offload_flags;
477 :
478 : /* Parses interface flags (up, down, enable, disable, etc.) */
479 : unformat_function_t unformat_vnet_hw_interface_flags;
480 : unformat_function_t unformat_vnet_sw_interface_flags;
481 :
482 : /* VLAN tag-rewrite */
483 : format_function_t format_vtr;
484 :
485 : /* Node runtime for interface output function. */
486 : typedef struct
487 : {
488 : u32 hw_if_index;
489 : u32 sw_if_index;
490 : u32 dev_instance;
491 : u32 is_deleted;
492 : } vnet_interface_output_runtime_t;
493 :
494 : /* Interface output function. */
495 : word vnet_sw_interface_compare (vnet_main_t * vnm, uword sw_if_index0,
496 : uword sw_if_index1);
497 : word vnet_hw_interface_compare (vnet_main_t * vnm, uword hw_if_index0,
498 : uword hw_if_index1);
499 :
500 : typedef enum
501 : {
502 : VNET_INTERFACE_OUTPUT_NEXT_DROP,
503 : VNET_INTERFACE_OUTPUT_NEXT_TX,
504 : } vnet_interface_output_next_t;
505 :
506 : typedef enum
507 : {
508 : VNET_INTERFACE_TX_NEXT_DROP,
509 : VNET_INTERFACE_TX_N_NEXT,
510 : } vnet_interface_tx_next_t;
511 :
512 : #define VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT VNET_INTERFACE_TX_N_NEXT
513 : #define VNET_SIMULATED_ETHERNET_TX_NEXT_L2_INPUT (VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT + 1)
514 :
515 : typedef enum
516 : {
517 : VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN,
518 : VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED,
519 : VNET_INTERFACE_OUTPUT_ERROR_NO_TX_QUEUE,
520 : } vnet_interface_output_error_t;
521 :
522 : /* Format for interface output traces. */
523 : u8 *format_vnet_interface_output_trace (u8 * s, va_list * va);
524 :
525 : serialize_function_t serialize_vnet_interface_state,
526 : unserialize_vnet_interface_state;
527 :
528 : /**
529 : * @brief Add buffer (vlib_buffer_t) to the trace
530 : *
531 : * @param *pm - pcap_main_t
532 : * @param *vm - vlib_main_t
533 : * @param buffer_index - u32
534 : * @param n_bytes_in_trace - u32
535 : *
536 : */
537 : static inline void
538 509783 : pcap_add_buffer (pcap_main_t *pm, struct vlib_main_t *vm, u32 buffer_index,
539 : u32 n_bytes_in_trace)
540 : {
541 509783 : vlib_buffer_t *b = vlib_get_buffer (vm, buffer_index);
542 509783 : u32 n = vlib_buffer_length_in_chain (vm, b);
543 509783 : i32 n_left = clib_min (n_bytes_in_trace, n);
544 509783 : f64 time_now = vlib_time_now (vm);
545 : void *d;
546 :
547 509783 : if (PREDICT_TRUE (pm->n_packets_captured < pm->n_packets_to_capture))
548 : {
549 509783 : time_now += vm->clib_time.init_reference_time;
550 509783 : clib_spinlock_lock_if_init (&pm->lock);
551 509783 : d = pcap_add_packet (pm, time_now, n_left, n);
552 : while (1)
553 160002 : {
554 669785 : u32 copy_length = clib_min ((u32) n_left, b->current_length);
555 669785 : clib_memcpy_fast (d, b->data + b->current_data, copy_length);
556 669785 : n_left -= b->current_length;
557 669785 : if (n_left <= 0)
558 509783 : break;
559 160002 : d += b->current_length;
560 160002 : ASSERT (b->flags & VLIB_BUFFER_NEXT_PRESENT);
561 160002 : b = vlib_get_buffer (vm, b->next_buffer);
562 : }
563 509783 : clib_spinlock_unlock_if_init (&pm->lock);
564 : }
565 509783 : }
566 :
567 : typedef struct
568 : {
569 : vnet_hw_if_caps_t val;
570 : vnet_hw_if_caps_t mask;
571 : } vnet_hw_if_caps_change_t;
572 :
573 : void vnet_hw_if_change_caps (vnet_main_t *vnm, u32 hw_if_index,
574 : vnet_hw_if_caps_change_t *caps);
575 :
576 : static_always_inline void
577 283 : vnet_hw_if_set_caps (vnet_main_t *vnm, u32 hw_if_index, vnet_hw_if_caps_t caps)
578 : {
579 283 : vnet_hw_if_caps_change_t cc = { .val = caps, .mask = caps };
580 283 : vnet_hw_if_change_caps (vnm, hw_if_index, &cc);
581 283 : }
582 :
583 : static_always_inline void
584 0 : vnet_hw_if_unset_caps (vnet_main_t *vnm, u32 hw_if_index,
585 : vnet_hw_if_caps_t caps)
586 : {
587 0 : vnet_hw_if_caps_change_t cc = { .val = 0, .mask = caps };
588 0 : vnet_hw_if_change_caps (vnm, hw_if_index, &cc);
589 0 : }
590 :
591 : #endif /* included_vnet_interface_funcs_h */
592 :
593 : /*
594 : * fd.io coding-style-patch-verification: ON
595 : *
596 : * Local Variables:
597 : * eval: (c-set-style "gnu")
598 : * End:
599 : */
|