FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
interface.c
Go to the documentation of this file.
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.c: VNET interfaces/sub-interfaces
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 #include <vnet/vnet.h>
41 #include <vnet/plugin/plugin.h>
42 #include <vnet/fib/ip6_fib.h>
43 #include <vnet/adj/adj.h>
44 
45 #define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0)
46 #define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1)
47 
49  u32 hw_if_index,
50  u32 flags,
51  u32 helper_flags);
52 
54  u32 sw_if_index,
55  u32 flags,
56  u32 helper_flags);
57 
59  u32 hw_if_index,
60  u32 hw_class_index,
61  u32 redistribute);
62 
63 typedef struct
64 {
65  /* Either sw or hw interface index. */
67 
68  /* Flags. */
71 
72 static void
74 {
76  va_arg (*va, vnet_sw_hw_interface_state_t *);
77  u32 n = va_arg (*va, u32);
78  u32 i;
79  for (i = 0; i < n; i++)
80  {
81  serialize_integer (m, s[i].sw_hw_if_index,
82  sizeof (s[i].sw_hw_if_index));
83  serialize_integer (m, s[i].flags, sizeof (s[i].flags));
84  }
85 }
86 
87 static void
89  va_list * va)
90 {
92  va_arg (*va, vnet_sw_hw_interface_state_t *);
93  u32 n = va_arg (*va, u32);
94  u32 i;
95  for (i = 0; i < n; i++)
96  {
97  unserialize_integer (m, &s[i].sw_hw_if_index,
98  sizeof (s[i].sw_hw_if_index));
99  unserialize_integer (m, &s[i].flags, sizeof (s[i].flags));
100  }
101 }
102 
103 static void
105 {
107  va_arg (*va, vnet_sw_hw_interface_state_t *);
109 }
110 
111 static void
113 {
114  CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *);
116 
118 
121  /* helper_flags no redistribution */ 0);
122 }
123 
124 static void
126 {
127  CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *);
129 
131 
134  /* helper_flags no redistribution */ 0);
135 }
136 
137 MC_SERIALIZE_MSG (vnet_sw_interface_set_flags_msg, static) =
138 {
139 .name = "vnet_sw_interface_set_flags",.serialize =
142 
143 MC_SERIALIZE_MSG (vnet_hw_interface_set_flags_msg, static) =
144 {
145 .name = "vnet_hw_interface_set_flags",.serialize =
148 
149 void
151 {
152  vnet_main_t *vnm = va_arg (*va, vnet_main_t *);
153  vnet_sw_hw_interface_state_t *sts = 0, *st;
154  vnet_sw_interface_t *sif;
155  vnet_hw_interface_t *hif;
157 
158  /* Serialize hardware interface classes since they may have changed.
159  Must do this before sending up/down flags. */
160  /* *INDENT-OFF* */
161  pool_foreach (hif, im->hw_interfaces, ({
162  vnet_hw_interface_class_t * hw_class = vnet_get_hw_interface_class (vnm, hif->hw_class_index);
163  serialize_cstring (m, hw_class->name);
164  }));
165  /* *INDENT-ON* */
166 
167  /* Send sw/hw interface state when non-zero. */
168  /* *INDENT-OFF* */
169  pool_foreach (sif, im->sw_interfaces, ({
170  if (sif->flags != 0)
171  {
172  vec_add2 (sts, st, 1);
173  st->sw_hw_if_index = sif->sw_if_index;
174  st->flags = sif->flags;
175  }
176  }));
177  /* *INDENT-ON* */
178 
180 
181  if (sts)
182  _vec_len (sts) = 0;
183 
184  /* *INDENT-OFF* */
185  pool_foreach (hif, im->hw_interfaces, ({
186  if (hif->flags != 0)
187  {
188  vec_add2 (sts, st, 1);
189  st->sw_hw_if_index = hif->hw_if_index;
190  st->flags = hif->flags;
191  }
192  }));
193  /* *INDENT-ON* */
194 
196 
197  vec_free (sts);
198 }
199 
200 void
202 {
203  vnet_main_t *vnm = va_arg (*va, vnet_main_t *);
204  vnet_sw_hw_interface_state_t *sts = 0, *st;
205 
206  /* First set interface hardware class. */
207  {
209  vnet_hw_interface_t *hif;
210  char *class_name;
211  uword *p;
212  clib_error_t *error;
213 
214  /* *INDENT-OFF* */
215  pool_foreach (hif, im->hw_interfaces, ({
216  unserialize_cstring (m, &class_name);
217  p = hash_get_mem (im->hw_interface_class_by_name, class_name);
218  ASSERT (p != 0);
219  error = vnet_hw_interface_set_class_helper (vnm, hif->hw_if_index, p[0], /* redistribute */ 0);
220  if (error)
221  clib_error_report (error);
222  vec_free (class_name);
223  }));
224  /* *INDENT-ON* */
225  }
226 
228  vec_foreach (st, sts)
229  vnet_sw_interface_set_flags_helper (vnm, st->sw_hw_if_index, st->flags,
230  /* no distribute */ 0);
231  vec_free (sts);
232 
234  vec_foreach (st, sts)
235  vnet_hw_interface_set_flags_helper (vnm, st->sw_hw_if_index, st->flags,
236  /* no distribute */ 0);
237  vec_free (sts);
238 }
239 
240 static clib_error_t *
242  u32 flags,
243  _vnet_interface_function_list_elt_t *
244  elt)
245 {
246  clib_error_t *error = 0;
247 
248  while (elt)
249  {
250  error = elt->fp (vnm, if_index, flags);
251  if (error)
252  return error;
253  elt = elt->next_interface_function;
254  }
255  return error;
256 }
257 
258 static clib_error_t *
260  u32 is_create)
261 {
262  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
263  vnet_hw_interface_class_t *hw_class =
265  vnet_device_class_t *dev_class =
267  clib_error_t *error = 0;
268 
269  if (hw_class->interface_add_del_function
270  && (error =
271  hw_class->interface_add_del_function (vnm, hw_if_index, is_create)))
272  return error;
273 
274  if (dev_class->interface_add_del_function
275  && (error =
276  dev_class->interface_add_del_function (vnm, hw_if_index,
277  is_create)))
278  return error;
279 
281  (vnm, hw_if_index, is_create, vnm->hw_interface_add_del_functions);
282 
283  return error;
284 }
285 
286 static clib_error_t *
288  u32 is_create)
289 {
291  (vnm, sw_if_index, is_create, vnm->sw_interface_add_del_functions);
292 }
293 
294 #define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE (1 << 0)
295 #define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE (1 << 1)
296 
297 static clib_error_t *
299  u32 flags, u32 helper_flags)
300 {
301  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
302  vnet_hw_interface_class_t *hw_class =
304  vnet_device_class_t *dev_class =
306  vlib_main_t *vm = vnm->vlib_main;
307  u32 mask;
308  clib_error_t *error = 0;
309  u32 is_create =
310  (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE) != 0;
311 
312  mask =
315  flags &= mask;
316 
317  /* Call hardware interface add/del callbacks. */
318  if (is_create)
319  call_hw_interface_add_del_callbacks (vnm, hw_if_index, is_create);
320 
321  /* Already in the desired state? */
322  if (!is_create && (hi->flags & mask) == flags)
323  goto done;
324 
325  /* Some interface classes do not redistribute (e.g. are local). */
326  if (!dev_class->redistribute)
328 
329  if (vm->mc_main
331  {
333  s.sw_hw_if_index = hw_if_index;
334  s.flags = flags;
335  mc_serialize (vm->mc_main, &vnet_hw_interface_set_flags_msg, &s);
336  }
337 
340  {
341  /* Do hardware class (e.g. ethernet). */
342  if (hw_class->link_up_down_function
343  && (error = hw_class->link_up_down_function (vnm, hw_if_index,
344  flags)))
345  goto done;
346 
348  (vnm, hw_if_index, flags, vnm->hw_interface_link_up_down_functions);
349 
350  if (error)
351  goto done;
352  }
353 
354  hi->flags &= ~mask;
355  hi->flags |= flags;
356 
357 done:
358  return error;
359 }
360 
361 static clib_error_t *
363  u32 flags, u32 helper_flags)
364 {
365  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
366  vlib_main_t *vm = vnm->vlib_main;
367  u32 mask;
368  clib_error_t *error = 0;
369  u32 is_create =
370  (helper_flags & VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE) != 0;
371  u32 old_flags;
372 
374  flags &= mask;
375 
376  if (is_create)
377  {
378  error =
379  call_sw_interface_add_del_callbacks (vnm, sw_if_index, is_create);
380  if (error)
381  goto done;
382 
384  {
385  /* Notify everyone when the interface is created as admin up */
386  error = call_elf_section_interface_callbacks (vnm, sw_if_index,
387  flags,
388  vnm->
389  sw_interface_admin_up_down_functions);
390  if (error)
391  goto done;
392  }
393  }
394  else
395  {
396  vnet_sw_interface_t *si_sup = si;
397 
398  /* Check that super interface is in correct state. */
399  if (si->type == VNET_SW_INTERFACE_TYPE_SUB)
400  {
401  si_sup = vnet_get_sw_interface (vnm, si->sup_sw_if_index);
402 
403  /* Check to see if we're bringing down the soft interface and if it's parent is up */
404  if ((flags != (si_sup->flags & mask)) &&
405  (!((flags == 0)
406  && ((si_sup->flags & mask) ==
408  {
409  error = clib_error_return (0, "super-interface %U must be %U",
411  si_sup,
413  flags);
414  goto done;
415  }
416  }
417 
418  /* Donot change state for slave link of bonded interfaces */
420  {
421  error = clib_error_return
422  (0, "not allowed as %U belong to a BondEthernet interface",
424  goto done;
425  }
426 
427  /* Already in the desired state? */
428  if ((si->flags & mask) == flags)
429  goto done;
430 
431  /* Sub-interfaces of hardware interfaces that do no redistribute,
432  do not redistribute themselves. */
433  if (si_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
434  {
436  vnet_get_hw_interface (vnm, si_sup->hw_if_index);
437  vnet_device_class_t *dev_class =
439  if (!dev_class->redistribute)
440  helper_flags &=
442  }
443 
444  if (vm->mc_main
445  && (helper_flags &
447  {
449  s.sw_hw_if_index = sw_if_index;
450  s.flags = flags;
451  mc_serialize (vm->mc_main, &vnet_sw_interface_set_flags_msg, &s);
452  }
453 
454  /* set the flags now before invoking the registered clients
455  * so that the state they query is consistent with the state here notified */
456  old_flags = si->flags;
457  si->flags &= ~mask;
458  si->flags |= flags;
459  if ((flags | old_flags) & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
461  (vnm, sw_if_index, flags,
463  si->flags = old_flags;
464 
465  if (error)
466  goto done;
467 
469  {
472  vnet_hw_interface_class_t *hw_class =
474  vnet_device_class_t *dev_class =
476 
477  /* save the si admin up flag */
478  old_flags = si->flags;
479 
480  /* update si admin up flag in advance if we are going admin down */
481  if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
482  si->flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
483 
484  if (dev_class->admin_up_down_function
485  && (error = dev_class->admin_up_down_function (vnm,
486  si->hw_if_index,
487  flags)))
488  {
489  /* restore si admin up flag to it's original state on errors */
490  si->flags = old_flags;
491  goto done;
492  }
493 
494  if (hw_class->admin_up_down_function
495  && (error = hw_class->admin_up_down_function (vnm,
496  si->hw_if_index,
497  flags)))
498  {
499  /* restore si admin up flag to it's original state on errors */
500  si->flags = old_flags;
501  goto done;
502  }
503 
504  /* Admin down implies link down. */
505  if (!(flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
508  hi->flags &
510  helper_flags);
511  }
512  }
513 
514  si->flags &= ~mask;
515  si->flags |= flags;
516 
517 done:
518  return error;
519 }
520 
521 clib_error_t *
523 {
525  (vnm, hw_if_index, flags,
527 }
528 
529 clib_error_t *
531 {
533  (vnm, sw_if_index, flags,
535 }
536 
537 static u32
539  vnet_sw_interface_t * template)
540 {
543  u32 sw_if_index;
544 
545  pool_get (im->sw_interfaces, sw);
546  sw_if_index = sw - im->sw_interfaces;
547 
548  sw[0] = template[0];
549 
550  sw->flags = 0;
551  sw->sw_if_index = sw_if_index;
553  sw->sup_sw_if_index = sw->sw_if_index;
554 
555  /* Allocate counters for this interface. */
556  {
557  u32 i;
558 
560 
561  for (i = 0; i < vec_len (im->sw_if_counters); i++)
562  {
563  vlib_validate_simple_counter (&im->sw_if_counters[i], sw_if_index);
564  vlib_zero_simple_counter (&im->sw_if_counters[i], sw_if_index);
565  }
566 
567  for (i = 0; i < vec_len (im->combined_sw_if_counters); i++)
568  {
570  sw_if_index);
572  sw_if_index);
573  }
574 
576  }
577 
578  return sw_if_index;
579 }
580 
581 clib_error_t *
583  u32 * sw_if_index)
584 {
585  clib_error_t *error;
587  vnet_device_class_t *dev_class;
588 
589  hi = vnet_get_sup_hw_interface (vnm, template->sup_sw_if_index);
590  dev_class = vnet_get_device_class (vnm, hi->dev_class_index);
591 
592  if (template->type == VNET_SW_INTERFACE_TYPE_SUB &&
593  dev_class->subif_add_del_function)
594  {
595  error = dev_class->subif_add_del_function (vnm, hi->hw_if_index,
596  (struct vnet_sw_interface_t
597  *) template, 1);
598  if (error)
599  return error;
600  }
601 
602  *sw_if_index = vnet_create_sw_interface_no_callbacks (vnm, template);
604  (vnm, *sw_if_index, template->flags,
606 
607  if (error)
608  {
609  /* undo the work done by vnet_create_sw_interface_no_callbacks() */
611  vnet_sw_interface_t *sw =
612  pool_elt_at_index (im->sw_interfaces, *sw_if_index);
613  pool_put (im->sw_interfaces, sw);
614  }
615 
616  return error;
617 }
618 
619 void
621 {
623  vnet_sw_interface_t *sw =
624  pool_elt_at_index (im->sw_interfaces, sw_if_index);
625 
626  /* Bring down interface in case it is up. */
627  if (sw->flags != 0)
628  vnet_sw_interface_set_flags (vnm, sw_if_index, /* flags */ 0);
629 
630  call_sw_interface_add_del_callbacks (vnm, sw_if_index, /* is_create */ 0);
631 
632  pool_put (im->sw_interfaces, sw);
633 }
634 
635 static void
637  u32 node_index, vnet_device_class_t * dev_class)
638 {
639  vlib_node_t *n = vlib_get_node (vm, node_index);
640 
641  n->function = dev_class->tx_function;
642  n->format_trace = dev_class->format_tx_trace;
643 
644  vlib_register_errors (vm, node_index,
645  dev_class->tx_function_n_errors,
646  dev_class->tx_function_error_strings);
647 }
648 
649 static void
651  u32 node_index, vnet_hw_interface_class_t * hw_class)
652 {
653  vlib_node_t *n = vlib_get_node (vm, node_index);
654  n->format_buffer = hw_class->format_header;
655  n->unformat_buffer = hw_class->unformat_header;
656 }
657 
658 /* Register an interface instance. */
659 u32
661  u32 dev_class_index,
662  u32 dev_instance,
663  u32 hw_class_index, u32 hw_instance)
664 {
667  vnet_device_class_t *dev_class =
668  vnet_get_device_class (vnm, dev_class_index);
669  vnet_hw_interface_class_t *hw_class =
670  vnet_get_hw_interface_class (vnm, hw_class_index);
671  vlib_main_t *vm = vnm->vlib_main;
672  u32 hw_index;
673  char *tx_node_name, *output_node_name;
674 
675  pool_get (im->hw_interfaces, hw);
676 
677  hw_index = hw - im->hw_interfaces;
678  hw->hw_if_index = hw_index;
679 
680  if (dev_class->format_device_name)
681  hw->name = format (0, "%U", dev_class->format_device_name, dev_instance);
682  else if (hw_class->format_interface_name)
683  hw->name = format (0, "%U", hw_class->format_interface_name,
684  dev_instance);
685  else
686  hw->name = format (0, "%s%x", hw_class->name, dev_instance);
687 
688  if (!im->hw_interface_by_name)
689  im->hw_interface_by_name = hash_create_vec ( /* size */ 0,
690  sizeof (hw->name[0]),
691  sizeof (uword));
692 
693  hash_set_mem (im->hw_interface_by_name, hw->name, hw_index);
694 
695  /* Make hardware interface point to software interface. */
696  {
698 
699  memset (&sw, 0, sizeof (sw));
701  sw.hw_if_index = hw_index;
703  }
704 
705  hw->dev_class_index = dev_class_index;
706  hw->dev_instance = dev_instance;
707  hw->hw_class_index = hw_class_index;
708  hw->hw_instance = hw_instance;
709 
710  hw->max_rate_bits_per_sec = 0;
711  hw->min_packet_bytes = 0;
713  hw->max_l3_packet_bytes[VLIB_RX] = ~0;
714  hw->max_l3_packet_bytes[VLIB_TX] = ~0;
715 
716  tx_node_name = (char *) format (0, "%v-tx", hw->name);
717  output_node_name = (char *) format (0, "%v-output", hw->name);
718 
719  /* If we have previously deleted interface nodes, re-use them. */
720  if (vec_len (im->deleted_hw_interface_nodes) > 0)
721  {
724  vlib_node_t *node;
725  vlib_node_runtime_t *nrt;
726 
727  hn = vec_end (im->deleted_hw_interface_nodes) - 1;
728 
729  hw->tx_node_index = hn->tx_node_index;
731 
732  vlib_node_rename (vm, hw->tx_node_index, "%v", tx_node_name);
733  vlib_node_rename (vm, hw->output_node_index, "%v", output_node_name);
734 
736  ASSERT (rt->is_deleted == 1);
737  rt->is_deleted = 0;
738  rt->hw_if_index = hw_index;
739  rt->sw_if_index = hw->sw_if_index;
740  rt->dev_instance = hw->dev_instance;
741 
743  rt->hw_if_index = hw_index;
744  rt->sw_if_index = hw->sw_if_index;
745  rt->dev_instance = hw->dev_instance;
746 
747  /* The new class may differ from the old one.
748  * Functions have to be updated. */
749  node = vlib_get_node (vm, hw->output_node_index);
750  node->function = dev_class->no_flatten_output_chains ?
755  nrt->function = node->function;
756 
757  node = vlib_get_node (vm, hw->tx_node_index);
758  node->function = dev_class->tx_function;
759  node->format_trace = dev_class->format_tx_trace;
760  nrt = vlib_node_get_runtime (vm, hw->tx_node_index);
761  nrt->function = node->function;
762 
764  _vec_len (im->deleted_hw_interface_nodes) -= 1;
765  }
766  else
767  {
770  .hw_if_index = hw_index,
771  .sw_if_index = hw->sw_if_index,
772  .dev_instance = hw->dev_instance,
773  .is_deleted = 0,
774  };
775 
776  memset (&r, 0, sizeof (r));
777  r.type = VLIB_NODE_TYPE_INTERNAL;
778  r.runtime_data = &rt;
779  r.runtime_data_bytes = sizeof (rt);
780  r.scalar_size = 0;
781  r.vector_size = sizeof (u32);
782 
783  r.flags = VLIB_NODE_FLAG_IS_OUTPUT;
784  r.name = tx_node_name;
785  r.function = dev_class->tx_function;
786 
787  hw->tx_node_index = vlib_register_node (vm, &r);
788 
790  "error-drop",
792 
793  r.flags = 0;
794  r.name = output_node_name;
795  r.function = dev_class->no_flatten_output_chains ?
798  r.format_trace = format_vnet_interface_output_trace;
799 
800  {
801  static char *e[] = {
802  "interface is down",
803  "interface is deleted",
804  };
805 
806  r.n_errors = ARRAY_LEN (e);
807  r.error_strings = e;
808  }
809  hw->output_node_index = vlib_register_node (vm, &r);
810 
811 #define _(sym,str) vlib_node_add_named_next_with_slot (vm, \
812  hw->output_node_index, str, \
813  VNET_INTERFACE_OUTPUT_NEXT_##sym);
815 #undef _
817  "error-drop",
820  hw->tx_node_index,
822  }
823 
824  setup_output_node (vm, hw->output_node_index, hw_class);
825  setup_tx_node (vm, hw->tx_node_index, dev_class);
826 
827  /* Call all up/down callbacks with zero flags when interface is created. */
828  vnet_sw_interface_set_flags_helper (vnm, hw->sw_if_index, /* flags */ 0,
830  vnet_hw_interface_set_flags_helper (vnm, hw_index, /* flags */ 0,
832 
833  return hw_index;
834 }
835 
836 void
838 {
840  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
841  vlib_main_t *vm = vnm->vlib_main;
842 
843  /* If it is up, mark it down. */
844  if (hw->flags != 0)
845  vnet_hw_interface_set_flags (vnm, hw_if_index, /* flags */ 0);
846 
847  /* Call delete callbacks. */
848  call_hw_interface_add_del_callbacks (vnm, hw_if_index, /* is_create */ 0);
849 
850  /* Delete software interface corresponding to hardware interface. */
852 
853  /* Delete any sub-interfaces. */
854  {
855  u32 id, sw_if_index;
856  /* *INDENT-OFF* */
857  hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id, ({
858  vnet_delete_sw_interface (vnm, sw_if_index);
859  }));
860  /* *INDENT-ON* */
861  }
862 
863  {
867 
868  /* Mark node runtime as deleted so output node (if called) will drop packets. */
869  rt->is_deleted = 1;
870 
872  "interface-%d-output-deleted", hw_if_index);
873  vlib_node_rename (vm, hw->tx_node_index, "interface-%d-tx-deleted",
874  hw_if_index);
876  dn->tx_node_index = hw->tx_node_index;
878  }
879 
881  vec_free (hw->name);
882 
883  pool_put (im->hw_interfaces, hw);
884 }
885 
886 static void
888 {
889  u32 hw_if_index = va_arg (*va, u32);
890  char *hw_class_name = va_arg (*va, char *);
891  serialize_integer (m, hw_if_index, sizeof (hw_if_index));
892  serialize_cstring (m, hw_class_name);
893 }
894 
895 static void
897 {
898  CLIB_UNUSED (mc_main_t * mc) = va_arg (*va, mc_main_t *);
899  vnet_main_t *vnm = vnet_get_main ();
900  u32 hw_if_index;
901  char *hw_class_name;
902  uword *p;
903  clib_error_t *error;
904 
905  unserialize_integer (m, &hw_if_index, sizeof (hw_if_index));
906  unserialize_cstring (m, &hw_class_name);
907  p =
908  hash_get (vnm->interface_main.hw_interface_class_by_name, hw_class_name);
909  ASSERT (p != 0);
910  error = vnet_hw_interface_set_class_helper (vnm, hw_if_index, p[0],
911  /* redistribute */ 0);
912  if (error)
913  clib_error_report (error);
914 }
915 
916 MC_SERIALIZE_MSG (vnet_hw_interface_set_class_msg, static) =
917 {
918 .name = "vnet_hw_interface_set_class",.serialize =
921 
922 void
924  u32 hw_class_index, u32 hw_instance)
925 {
926  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
928  vnet_get_hw_interface_class (vnm, hw_class_index);
929 
930  hi->hw_class_index = hw_class_index;
931  hi->hw_instance = hw_instance;
933 }
934 
935 static clib_error_t *
937  u32 hw_class_index, u32 redistribute)
938 {
939  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
941  vnet_hw_interface_class_t *old_class =
943  vnet_hw_interface_class_t *new_class =
944  vnet_get_hw_interface_class (vnm, hw_class_index);
945  vnet_device_class_t *dev_class =
947  clib_error_t *error = 0;
948 
949  /* New class equals old class? Nothing to do. */
950  if (hi->hw_class_index == hw_class_index)
951  return 0;
952 
953  /* No need (and incorrect since admin up flag may be set) to do error checking when
954  receiving unserialize message. */
955  if (redistribute)
956  {
958  return clib_error_return (0,
959  "%v must be admin down to change class from %s to %s",
960  hi->name, old_class->name, new_class->name);
961 
962  /* Make sure interface supports given class. */
963  if ((new_class->is_valid_class_for_interface
964  && !new_class->is_valid_class_for_interface (vnm, hw_if_index,
965  hw_class_index))
966  || (dev_class->is_valid_class_for_interface
967  && !dev_class->is_valid_class_for_interface (vnm, hw_if_index,
968  hw_class_index)))
969  return clib_error_return (0,
970  "%v class cannot be changed from %s to %s",
971  hi->name, old_class->name, new_class->name);
972 
973  if (vnm->vlib_main->mc_main)
974  {
976  &vnet_hw_interface_set_class_msg, hw_if_index,
977  new_class->name);
978  return 0;
979  }
980  }
981 
982  if (old_class->hw_class_change)
983  old_class->hw_class_change (vnm, hw_if_index, old_class->index,
984  new_class->index);
985 
986  vnet_hw_interface_init_for_class (vnm, hw_if_index, new_class->index,
987  /* instance */ ~0);
988 
989  if (new_class->hw_class_change)
990  new_class->hw_class_change (vnm, hw_if_index, old_class->index,
991  new_class->index);
992 
993  if (dev_class->hw_class_change)
994  dev_class->hw_class_change (vnm, hw_if_index, new_class->index);
995 
996  return error;
997 }
998 
999 clib_error_t *
1001  u32 hw_class_index)
1002 {
1003  return vnet_hw_interface_set_class_helper (vnm, hw_if_index, hw_class_index,
1004  /* redistribute */ 1);
1005 }
1006 
1007 static int
1009  u32 hw_if_index,
1010  u32 node_index,
1011  u32 redistribute)
1012 {
1013  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1015  (vnm, hi->dev_class_index);
1016 
1017  if (redistribute)
1018  {
1019  /* $$$$ fixme someday maybe */
1020  ASSERT (vnm->vlib_main->mc_main == 0);
1021  }
1022  if (dev_class->rx_redirect_to_node)
1023  {
1024  dev_class->rx_redirect_to_node (vnm, hw_if_index, node_index);
1025  return 0;
1026  }
1027 
1028  return VNET_API_ERROR_UNIMPLEMENTED;
1029 }
1030 
1031 int
1033  u32 node_index)
1034 {
1035  return vnet_hw_interface_rx_redirect_to_node_helper (vnm, hw_if_index,
1036  node_index,
1037  1 /* redistribute */ );
1038 }
1039 
1040 word
1042  uword sw_if_index0, uword sw_if_index1)
1043 {
1044  vnet_sw_interface_t *sup0 = vnet_get_sup_sw_interface (vnm, sw_if_index0);
1045  vnet_sw_interface_t *sup1 = vnet_get_sup_sw_interface (vnm, sw_if_index1);
1048 
1049  if (h0 != h1)
1050  return vec_cmp (h0->name, h1->name);
1051  return (word) h0->hw_instance - (word) h1->hw_instance;
1052 }
1053 
1054 word
1056  uword hw_if_index0, uword hw_if_index1)
1057 {
1058  vnet_hw_interface_t *h0 = vnet_get_hw_interface (vnm, hw_if_index0);
1059  vnet_hw_interface_t *h1 = vnet_get_hw_interface (vnm, hw_if_index1);
1060 
1061  if (h0 != h1)
1062  return vec_cmp (h0->name, h1->name);
1063  return (word) h0->hw_instance - (word) h1->hw_instance;
1064 }
1065 
1066 int
1068 {
1069  vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
1072 
1073  return (hc->flags & VNET_HW_INTERFACE_CLASS_FLAG_P2P);
1074 }
1075 
1076 clib_error_t *
1078 {
1079  vnet_main_t *vnm = vnet_get_main ();
1081  vlib_buffer_t *b = 0;
1082  vnet_buffer_opaque_t *o = 0;
1083 
1084  /*
1085  * Keep people from shooting themselves in the foot.
1086  */
1087  if (sizeof (b->opaque) != sizeof (vnet_buffer_opaque_t))
1088  {
1089 #define _(a) if (sizeof(o->a) > sizeof (o->unused)) \
1090  clib_warning \
1091  ("FATAL: size of opaque union subtype %s is %d (max %d)", \
1092  #a, sizeof(o->a), sizeof (o->unused));
1094 #undef _
1095 
1096  return clib_error_return
1097  (0, "FATAL: size of vlib buffer opaque %d, size of vnet opaque %d",
1098  sizeof (b->opaque), sizeof (vnet_buffer_opaque_t));
1099  }
1100 
1103  im->sw_if_counter_lock[0] = 1; /* should be no need */
1104 
1114 
1119 
1120  im->sw_if_counter_lock[0] = 0;
1121 
1122  im->device_class_by_name = hash_create_string ( /* size */ 0,
1123  sizeof (uword));
1124  {
1126 
1127  c = vnm->device_class_registrations;
1128 
1129  while (c)
1130  {
1131  c->index = vec_len (im->device_classes);
1132  hash_set_mem (im->device_class_by_name, c->name, c->index);
1133  vec_add1 (im->device_classes, c[0]);
1134  c = c->next_class_registration;
1135  }
1136  }
1137 
1138  im->hw_interface_class_by_name = hash_create_string ( /* size */ 0,
1139  sizeof (uword));
1140 
1141  im->sw_if_index_by_sup_and_sub = hash_create_mem (0, sizeof (u64),
1142  sizeof (uword));
1143  {
1145 
1147 
1148  while (c)
1149  {
1150  c->index = vec_len (im->hw_interface_classes);
1151  hash_set_mem (im->hw_interface_class_by_name, c->name, c->index);
1152 
1153  if (NULL == c->build_rewrite)
1154  c->build_rewrite = default_build_rewrite;
1155  if (NULL == c->update_adjacency)
1156  c->update_adjacency = default_update_adjacency;
1157 
1158  vec_add1 (im->hw_interface_classes, c[0]);
1159  c = c->next_class_registration;
1160  }
1161  }
1162 
1163  {
1164  clib_error_t *error;
1165 
1167  return error;
1168 
1169  return error;
1170  }
1171 }
1172 
1174 
1175 /* Kludge to renumber interface names [only!] */
1176 int
1177 vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance)
1178 {
1179  int rv;
1180  vnet_main_t *vnm = vnet_get_main ();
1182  vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
1183 
1185  (vnm, hi->dev_class_index);
1186 
1187  if (dev_class->name_renumber == 0 || dev_class->format_device_name == 0)
1188  return VNET_API_ERROR_UNIMPLEMENTED;
1189 
1190  rv = dev_class->name_renumber (hi, new_show_dev_instance);
1191 
1192  if (rv)
1193  return rv;
1194 
1196  vec_free (hi->name);
1197  /* Use the mapping we set up to call it Ishmael */
1198  hi->name = format (0, "%U", dev_class->format_device_name,
1199  hi->dev_instance);
1200 
1202  return rv;
1203 }
1204 
1205 int
1207  vlib_main_t * vm,
1208  u32 sw_if_index,
1209  intf_output_feat_t feature, int is_add)
1210 {
1211  vnet_sw_interface_t *sw;
1212 
1213  sw = vnet_get_sw_interface (vnm, sw_if_index);
1214 
1215  if (is_add)
1216  {
1217 
1218  sw->output_feature_bitmap |= (1 << feature);
1220 
1221  }
1222  else
1223  { /* delete */
1224 
1225  sw->output_feature_bitmap &= ~(1 << feature);
1226  if (sw->output_feature_bitmap == (1 << INTF_OUTPUT_FEAT_DONE))
1227  sw->output_feature_bitmap = 0;
1228 
1229  }
1230  return 0;
1231 }
1232 
1233 clib_error_t *
1234 vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index, char *new_name)
1235 {
1237  vlib_main_t *vm = vnm->vlib_main;
1238  vnet_hw_interface_t *hw;
1239  u8 *old_name;
1240  clib_error_t *error = 0;
1241 
1242  hw = vnet_get_hw_interface (vnm, hw_if_index);
1243  if (!hw)
1244  {
1245  return clib_error_return (0,
1246  "unable to find hw interface for index %u",
1247  hw_if_index);
1248  }
1249 
1250  old_name = hw->name;
1251 
1252  /* set new hw->name */
1253  hw->name = format (0, "%s", new_name);
1254 
1255  /* remove the old name to hw_if_index mapping and install the new one */
1256  hash_unset_mem (im->hw_interface_by_name, old_name);
1257  hash_set_mem (im->hw_interface_by_name, hw->name, hw_if_index);
1258 
1259  /* rename tx/output nodes */
1260  vlib_node_rename (vm, hw->tx_node_index, "%v-tx", hw->name);
1261  vlib_node_rename (vm, hw->output_node_index, "%v-output", hw->name);
1262 
1263  /* free the old name vector */
1264  vec_free (old_name);
1265 
1266  return error;
1267 }
1268 
1269 static clib_error_t *
1271  u32 hw_if_index, u64 mac_address)
1272 {
1273  clib_error_t *error = 0;
1274  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1275 
1276  if (hi->hw_address)
1277  {
1278  vnet_device_class_t *dev_class =
1280  if (dev_class->mac_addr_change_function)
1281  {
1282  error =
1283  dev_class->mac_addr_change_function (vnet_get_hw_interface
1284  (vnm, hw_if_index),
1285  (char *) &mac_address);
1286  }
1287  if (!error)
1288  {
1290  ethernet_interface_t *ei =
1292 
1293  vec_validate (hi->hw_address,
1294  STRUCT_SIZE_OF (ethernet_header_t, src_address) - 1);
1295  clib_memcpy (hi->hw_address, &mac_address,
1296  vec_len (hi->hw_address));
1297 
1298  clib_memcpy (ei->address, (u8 *) & mac_address,
1299  sizeof (ei->address));
1300  ethernet_arp_change_mac (vnm, hw_if_index);
1301  ethernet_ndp_change_mac (vnm->vlib_main, hw_if_index);
1302  }
1303  else
1304  {
1305  error =
1306  clib_error_return (0,
1307  "MAC Address Change is not supported on this interface");
1308  }
1309  }
1310  else
1311  {
1312  error =
1313  clib_error_return (0,
1314  "mac address change is not supported for interface index %u",
1315  hw_if_index);
1316  }
1317  return error;
1318 }
1319 
1320 clib_error_t *
1322  u64 mac_address)
1323 {
1325  (vnm, hw_if_index, mac_address);
1326 }
1327 
1330 {
1331  switch (link)
1332  {
1333  case VNET_LINK_IP4:
1334  return (VNET_L3_PACKET_TYPE_IP4);
1335  case VNET_LINK_IP6:
1336  return (VNET_L3_PACKET_TYPE_IP6);
1337  case VNET_LINK_MPLS:
1338  return (VNET_L3_PACKET_TYPE_MPLS_UNICAST);
1339  case VNET_LINK_ARP:
1340  return (VNET_L3_PACKET_TYPE_ARP);
1341  case VNET_LINK_ETHERNET:
1342  ASSERT (0);
1343  break;
1344  }
1345  ASSERT (0);
1346  return (0);
1347 }
1348 
1349 u8 *
1351  u32 sw_if_index,
1352  vnet_link_t link_type, const void *dst_address)
1353 {
1354  return (NULL);
1355 }
1356 
1357 void
1359 {
1360  u8 *rewrite;
1361 
1362  rewrite = vnet_build_rewrite_for_sw_interface (vnm, sw_if_index,
1363  adj_get_link_type (ai),
1364  NULL);
1365 
1367 }
1368 
1369 
1370 /*
1371  * fd.io coding-style-patch-verification: ON
1372  *
1373  * Local Variables:
1374  * eval: (c-set-style "gnu")
1375  * End:
1376  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
void serialize_vnet_interface_state(serialize_main_t *m, va_list *va)
Definition: interface.c:150
vmrglw vmrglh hi
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
#define CLIB_UNUSED(x)
Definition: clib.h:79
static clib_error_t * vnet_hw_interface_set_class_helper(vnet_main_t *vnm, u32 hw_if_index, u32 hw_class_index, u32 redistribute)
Definition: interface.c:936
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:522
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:110
volatile u32 * sw_if_counter_lock
Definition: interface.h:575
vnet_hw_interface_nodes_t * deleted_hw_interface_nodes
Definition: interface.h:579
#define INTF_OUTPUT_FEAT_DONE
Definition: interface.h:628
#define vec_serialize(m, v, f)
Definition: serialize.h:371
An indication that the rewrite is complete, i.e.
Definition: adj_nbr.h:98
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
vnet_interface_main_t interface_main
Definition: vnet.h:72
void * vnet_interface_output_node_multiarch_select(void)
uword vlib_node_add_next_with_slot(vlib_main_t *vm, uword node_index, uword next_node_index, uword slot)
Definition: node.c:156
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, u64 mac_address)
Definition: interface.c:1321
int vnet_hw_interface_rx_redirect_to_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: interface.c:1032
void vlib_register_errors(vlib_main_t *vm, u32 node_index, u32 n_errors, char *error_strings[])
Definition: error.c:145
int vnet_interface_add_del_feature(vnet_main_t *vnm, vlib_main_t *vm, u32 sw_if_index, intf_output_feat_t feature, int is_add)
Definition: interface.c:1206
vnet_link_t adj_get_link_type(adj_index_t ai)
Return the link type of the adjacency.
Definition: adj.c:259
#define NULL
Definition: clib.h:55
#define vec_unserialize(m, v, f)
Definition: serialize.h:374
format_function_t * format_trace
Definition: node.h:315
vnet_device_class_t * device_class_registrations
Definition: vnet.h:75
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
word vnet_sw_interface_compare(vnet_main_t *vnm, uword sw_if_index0, uword sw_if_index1)
Definition: interface.c:1041
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1177
_vnet_interface_function_list_elt_t * sw_interface_admin_up_down_functions
Definition: vnet.h:80
struct _vlib_node_registration vlib_node_registration_t
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:521
intf_output_feat_t
Definition: interface.h:619
#define hash_set_mem(h, key, value)
Definition: hash.h:274
MC_SERIALIZE_MSG(vnet_sw_interface_set_flags_msg, static)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
uword * sub_interface_sw_if_index_by_id
Definition: interface.h:423
static void unserialize_vnet_hw_interface_set_flags(serialize_main_t *m, va_list *va)
Definition: interface.c:125
#define clib_error_report(e)
Definition: error.h:125
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:348
struct _vnet_device_class vnet_device_class_t
#define mc_serialize(mc, msg, args...)
Definition: mc.h:651
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static clib_error_t * vnet_hw_interface_set_flags_helper(vnet_main_t *vnm, u32 hw_if_index, u32 flags, u32 helper_flags)
Definition: interface.c:298
#define VNET_HW_INTERFACE_FLAG_DUPLEX_MASK
Definition: interface.h:353
mc_main_t * mc_main
Definition: main.h:133
vlib_node_function_t * function
Definition: node.h:218
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:452
static void unserialize_vec_vnet_sw_hw_interface_state(serialize_main_t *m, va_list *va)
Definition: interface.c:88
#define VNET_HW_INTERFACE_FLAG_SPEED_MASK
Definition: interface.h:365
ethernet_main_t ethernet_main
Definition: ethernet.h:279
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
void default_update_adjacency(vnet_main_t *vnm, u32 sw_if_index, u32 ai)
Default adjacency update function.
Definition: interface.c:1358
vnet_l3_packet_type_t
Definition: l3_types.h:44
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
void vlib_worker_thread_node_runtime_update(void)
Definition: threads.c:826
vlib_node_function_t * function
Definition: node.h:416
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static u32 vnet_create_sw_interface_no_callbacks(vnet_main_t *vnm, vnet_sw_interface_t *template)
Definition: interface.c:538
static vnet_device_class_t * vnet_get_device_class(vnet_main_t *vnm, u32 dev_class_index)
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:577
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:418
void * vnet_interface_output_node_no_flatten_multiarch_select(void)
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * call_hw_interface_add_del_callbacks(vnet_main_t *vnm, u32 hw_if_index, u32 is_create)
Definition: interface.c:259
unsigned long u64
Definition: types.h:89
#define vec_end(v)
End (last data address) of vector.
#define vlib_call_init_function(vm, x)
Definition: init.h:161
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:660
_vnet_interface_function_list_elt_t * hw_interface_link_up_down_functions
Definition: vnet.h:78
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
char * name
The counter collection&#39;s name.
Definition: counter.h:68
uword * hw_interface_by_name
Definition: interface.h:557
void vlib_node_rename(vlib_main_t *vm, u32 node_index, char *fmt,...)
Definition: node.c:76
vnet_hw_interface_t * hw_interfaces
Definition: interface.h:554
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:637
#define hash_get(h, key)
Definition: hash.h:248
format_function_t format_vnet_sw_interface_name
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread u16 counters, and the shared vlib_counter_t...
Definition: counter.h:321
u8 * format_vnet_interface_output_trace(u8 *s, va_list *va)
#define hash_unset_mem(h, key)
Definition: hash.h:280
vlib_main_t * vlib_main
Definition: vnet.h:88
int vnet_sw_interface_is_p2p(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1067
#define VNET_SW_INTERFACE_FLAG_BOND_SLAVE
Definition: interface.h:499
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
static void serialize_vec_vnet_sw_hw_interface_state(serialize_main_t *m, va_list *va)
Definition: interface.c:73
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:571
static void * vlib_node_get_runtime_data(vlib_main_t *vm, u32 node_index)
Get node runtime private data by node index.
Definition: node_funcs.h:109
u8 * vnet_build_rewrite_for_sw_interface(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Definition: rewrite.c:297
static void unserialize_vnet_hw_interface_set_class(serialize_main_t *m, va_list *va)
Definition: interface.c:896
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:576
word vnet_hw_interface_compare(vnet_main_t *vnm, uword hw_if_index0, uword hw_if_index1)
Definition: interface.c:1055
format_function_t * format_buffer
Definition: node.h:311
uword * hw_interface_class_by_name
Definition: interface.h:564
void unserialize_cstring(serialize_main_t *m, char **s)
Definition: serialize.c:178
static clib_error_t * vnet_hw_interface_change_mac_address_helper(vnet_main_t *vnm, u32 hw_if_index, u64 mac_address)
Definition: interface.c:1270
void unserialize_vnet_interface_state(serialize_main_t *m, va_list *va)
Definition: interface.c:201
clib_error_t * vnet_rename_interface(vnet_main_t *vnm, u32 hw_if_index, char *new_name)
Definition: interface.c:1234
_vnet_interface_function_list_elt_t * sw_interface_add_del_functions
Definition: vnet.h:79
_vnet_interface_function_list_elt_t * hw_interface_add_del_functions
Definition: vnet.h:77
clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:671
svmdb_client_t * c
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:88
#define clib_memcpy(a, b, c)
Definition: string.h:64
unformat_function_t * unformat_buffer
Definition: node.h:312
static void vnet_interface_counter_unlock(vnet_interface_main_t *im)
Definition: interface.h:600
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
Definition: serialize.h:201
static void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
Definition: serialize.h:185
static clib_error_t * call_sw_interface_add_del_callbacks(vnet_main_t *vnm, u32 sw_if_index, u32 is_create)
Definition: interface.c:287
void vnet_hw_interface_init_for_class(vnet_main_t *vnm, u32 hw_if_index, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:923
#define ARRAY_LEN(x)
Definition: clib.h:59
static void setup_output_node(vlib_main_t *vm, u32 node_index, vnet_hw_interface_class_t *hw_class)
Definition: interface.c:650
u8 * default_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Return a complete, zero-length (aka dummy) rewrite.
Definition: interface.c:1350
format_function_t format_vnet_sw_interface_flags
static void unserialize_vnet_sw_interface_set_flags(serialize_main_t *m, va_list *va)
Definition: interface.c:112
#define VNET_INTERFACE_SET_FLAGS_HELPER_IS_CREATE
Definition: interface.c:294
static clib_error_t * vnet_sw_interface_set_flags_helper(vnet_main_t *vnm, u32 sw_if_index, u32 flags, u32 helper_flags)
Definition: interface.c:362
static void vnet_interface_counter_lock(vnet_interface_main_t *im)
Definition: interface.h:592
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
Definition: counter.c:98
Definition: mc.h:522
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:490
void ethernet_arp_change_mac(vnet_main_t *vnm, u32 sw_if_index)
Definition: arp.c:2339
u32 max_l3_packet_bytes[VLIB_N_RX_TX]
Definition: interface.h:420
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static void serialize_vnet_sw_hw_interface_set_flags(serialize_main_t *m, va_list *va)
Definition: interface.c:104
#define VNET_SW_INTERFACE_FLAG_PUNT
Definition: interface.h:493
static void setup_tx_node(vlib_main_t *vm, u32 node_index, vnet_device_class_t *dev_class)
Definition: interface.c:636
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
static vnet_hw_interface_class_t * vnet_get_hw_interface_class(vnet_main_t *vnm, u32 hw_class_index)
clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:683
static clib_error_t * call_elf_section_interface_callbacks(vnet_main_t *vnm, u32 if_index, u32 flags, _vnet_interface_function_list_elt_t *elt)
Definition: interface.c:241
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
Definition: counter.h:143
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:880
uword * device_class_by_name
Definition: interface.h:565
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:837
u64 uword
Definition: types.h:112
void serialize_cstring(serialize_main_t *m, char *s)
Definition: serialize.c:164
#define VLIB_NODE_FLAG_IS_OUTPUT
Definition: node.h:253
Definition: defs.h:47
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:644
i64 word
Definition: types.h:111
struct _vnet_hw_interface_class vnet_hw_interface_class_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
clib_error_t * vnet_interface_init(vlib_main_t *vm)
Definition: interface.c:1077
vnet_l3_packet_type_t vnet_link_to_l3_proto(vnet_link_t link)
Convert a link to to an Ethertype.
Definition: interface.c:1329
static clib_error_t * vnet_interface_cli_init(vlib_main_t *vm)
static int vnet_hw_interface_rx_redirect_to_node_helper(vnet_main_t *vnm, u32 hw_if_index, u32 node_index, u32 redistribute)
Definition: interface.c:1008
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:568
vnet_hw_interface_class_t * hw_interface_class_registrations
Definition: vnet.h:76
char * name
The counter collection&#39;s name.
Definition: counter.h:219
a point 2 point interface
Definition: interface.h:246
vnet_hw_interface_class_t * hw_interface_classes
Definition: interface.h:560
u32 opaque[8]
Opaque data used by sub-graphs for their own purposes.
Definition: buffer.h:133
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
static void serialize_vnet_hw_interface_set_class(serialize_main_t *m, va_list *va)
Definition: interface.c:887
#define foreach_intf_output_feat
Definition: interface.h:615
vnet_sw_interface_type_t type
Definition: interface.h:485
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
#define STRUCT_SIZE_OF(t, f)
Definition: clib.h:64
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
#define vec_foreach(var, vec)
Vector iterator.
void vnet_delete_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:620
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:530
vnet_device_class_t * device_classes
Definition: interface.h:561
u32 per_packet_overhead_bytes
Definition: interface.h:417
#define clib_error_return(e, args...)
Definition: error.h:111
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:582
#define foreach_buffer_opaque_union_subtype
Definition: buffer.h:70
uword vlib_node_add_named_next_with_slot(vlib_main_t *vm, uword node, char *name, uword slot)
Definition: node.c:213
u32 flags
Definition: vhost-user.h:75
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
ethernet_interface_t * interfaces
Definition: ethernet.h:243
void adj_nbr_update_rewrite(adj_index_t adj_index, adj_nbr_rewrite_flag_t flags, u8 *rewrite)
adj_nbr_update_rewrite
Definition: adj_nbr.c:250
#define VNET_INTERFACE_SET_FLAGS_HELPER_WANT_REDISTRIBUTE
Definition: interface.c:295
Definition: defs.h:46
void ethernet_ndp_change_mac(vlib_main_t *vm, u32 sw_if_index)
clib_error_t * vnet_hw_interface_set_class(vnet_main_t *vnm, u32 hw_if_index, u32 hw_class_index)
Definition: interface.c:1000