FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
interface_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * interface_api.c - vnet interface api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/ethernet/ethernet.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/fib/fib_table.h>
28 #include <vnet/mfib/mfib_table.h>
29 #include <vnet/l2/l2_vtr.h>
30 #include <vnet/vnet_msg_enum.h>
31 #include <vnet/fib/fib_api.h>
32 #include <vnet/mfib/mfib_table.h>
33 
34 #define vl_typedefs /* define message structures */
35 #include <vnet/vnet_all_api_h.h>
36 #undef vl_typedefs
37 
38 #define vl_endianfun /* define message structures */
39 #include <vnet/vnet_all_api_h.h>
40 #undef vl_endianfun
41 
42 /* instantiate all the print functions we know about */
43 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
44 #define vl_printfun
45 #include <vnet/vnet_all_api_h.h>
46 #undef vl_printfun
47 
50 
51 #define foreach_vpe_api_msg \
52 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
53 _(HW_INTERFACE_SET_MTU, hw_interface_set_mtu) \
54 _(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) \
55 _(WANT_INTERFACE_EVENTS, want_interface_events) \
56 _(SW_INTERFACE_DUMP, sw_interface_dump) \
57 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
58 _(SW_INTERFACE_SET_RX_MODE, sw_interface_set_rx_mode) \
59 _(SW_INTERFACE_RX_PLACEMENT_DUMP, sw_interface_rx_placement_dump) \
60 _(SW_INTERFACE_SET_RX_PLACEMENT, sw_interface_set_rx_placement) \
61 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
62 _(SW_INTERFACE_GET_TABLE, sw_interface_get_table) \
63 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
64 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
65 _(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) \
66 _(SW_INTERFACE_SET_MAC_ADDRESS, sw_interface_set_mac_address) \
67 _(SW_INTERFACE_GET_MAC_ADDRESS, sw_interface_get_mac_address) \
68 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
69 _(CREATE_SUBIF, create_subif) \
70 _(DELETE_SUBIF, delete_subif) \
71 _(CREATE_LOOPBACK, create_loopback) \
72 _(CREATE_LOOPBACK_INSTANCE, create_loopback_instance) \
73 _(DELETE_LOOPBACK, delete_loopback) \
74 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
75 _(COLLECT_DETAILED_INTERFACE_STATS, collect_detailed_interface_stats) \
76 _(SW_INTERFACE_SET_IP_DIRECTED_BROADCAST, \
77  sw_interface_set_ip_directed_broadcast)
78 
79 static void
81 {
82  vl_api_sw_interface_set_flags_reply_t *rmp;
83  vnet_main_t *vnm = vnet_get_main ();
84  int rv = 0;
85  clib_error_t *error;
86  u16 flags;
87 
89 
91 
92  error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
93  if (error)
94  {
95  rv = -1;
96  clib_error_report (error);
97  }
98 
100  REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
101 }
102 
103 static void
105 {
106  vl_api_hw_interface_set_mtu_reply_t *rmp;
107  vnet_main_t *vnm = vnet_get_main ();
108  u32 sw_if_index = ntohl (mp->sw_if_index);
109  u16 mtu = ntohs (mp->mtu);
111  int rv = 0;
112 
114 
115  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
117  {
118  rv = VNET_API_ERROR_INVALID_VALUE;
119  goto bad_sw_if_index;
120  }
121 
124 
125  if (!eif)
126  {
127  rv = VNET_API_ERROR_FEATURE_DISABLED;
128  goto bad_sw_if_index;
129  }
130 
131  if (mtu < hi->min_supported_packet_bytes)
132  {
133  rv = VNET_API_ERROR_INVALID_VALUE;
134  goto bad_sw_if_index;
135  }
136 
137  if (mtu > hi->max_supported_packet_bytes)
138  {
139  rv = VNET_API_ERROR_INVALID_VALUE;
140  goto bad_sw_if_index;
141  }
142 
143  vnet_hw_interface_set_mtu (vnm, si->hw_if_index, mtu);
144 
146  REPLY_MACRO (VL_API_HW_INTERFACE_SET_MTU_REPLY);
147 }
148 
149 static void
151 {
152  vl_api_sw_interface_set_mtu_reply_t *rmp;
153  vnet_main_t *vnm = vnet_get_main ();
154  u32 sw_if_index = ntohl (mp->sw_if_index);
155  int rv = 0;
156  int i;
157  u32 per_protocol_mtu[VNET_N_MTU];
158 
160 
161  for (i = 0; i < VNET_N_MTU; i++)
162  per_protocol_mtu[i] = ntohl (mp->mtu[i]);
163 
164  vnet_sw_interface_set_protocol_mtu (vnm, sw_if_index, per_protocol_mtu);
165 
167  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MTU_REPLY);
168 }
169 
170 static void
173 {
174  vl_api_sw_interface_set_ip_directed_broadcast_reply_t *rmp;
175  u32 sw_if_index = ntohl (mp->sw_if_index);
176  int rv = 0;
177 
179 
181  sw_if_index, mp->enable);
182 
184  REPLY_MACRO (VL_API_SW_INTERFACE_SET_IP_DIRECTED_BROADCAST_REPLY);
185 }
186 
187 static void
190  vnet_sw_interface_t * swif,
191  u8 * interface_name, u32 context)
192 {
195 
196  vl_api_sw_interface_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
197  clib_memset (mp, 0, sizeof (*mp));
198  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS);
199  mp->sw_if_index = ntohl (swif->sw_if_index);
200  mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index);
201  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
202  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
205  mp->link_speed = ntohl (hi->link_speed);
206  mp->link_mtu = ntohs (hi->max_packet_bytes);
207  mp->mtu[VNET_MTU_L3] = ntohl (swif->mtu[VNET_MTU_L3]);
208  mp->mtu[VNET_MTU_IP4] = ntohl (swif->mtu[VNET_MTU_IP4]);
209  mp->mtu[VNET_MTU_IP6] = ntohl (swif->mtu[VNET_MTU_IP6]);
210  mp->mtu[VNET_MTU_MPLS] = ntohl (swif->mtu[VNET_MTU_MPLS]);
211 
212  mp->context = context;
213 
214  strncpy ((char *) mp->interface_name,
215  (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
216 
217  /* Send the L2 address for ethernet physical intfcs */
218  if (swif->sup_sw_if_index == swif->sw_if_index
220  {
223 
224  ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
225  ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
226  clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
227  mp->l2_address_length = ntohl (sizeof (ei->address));
228  }
229  else if (swif->sup_sw_if_index != swif->sw_if_index)
230  {
231  vnet_sub_interface_t *sub = &swif->sub;
232  mp->sub_id = ntohl (sub->id);
233  mp->sub_dot1ad = sub->eth.flags.dot1ad;
234  mp->sub_number_of_tags =
235  sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
236  mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
237  mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
238  mp->sub_exact_match = sub->eth.flags.exact_match;
239  mp->sub_default = sub->eth.flags.default_sub;
240  mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
241  mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
242 
243  /* vlan tag rewrite data */
244  u32 vtr_op = L2_VTR_DISABLED;
245  u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
246 
247  if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
248  &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
249  {
250  // error - default to disabled
251  mp->vtr_op = ntohl (L2_VTR_DISABLED);
252  clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
253  swif->sw_if_index);
254  }
255  else
256  {
257  mp->vtr_op = ntohl (vtr_op);
258  mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
259  mp->vtr_tag1 = ntohl (vtr_tag1);
260  mp->vtr_tag2 = ntohl (vtr_tag2);
261  }
262  }
263 
264  /* pbb tag rewrite data */
265  ethernet_header_t eth_hdr;
266  u32 vtr_op = L2_VTR_DISABLED;
267  u16 outer_tag = 0;
268  u16 b_vlanid = 0;
269  u32 i_sid = 0;
270  clib_memset (&eth_hdr, 0, sizeof (eth_hdr));
271 
272  if (!l2pbb_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
273  &vtr_op, &outer_tag, &eth_hdr, &b_vlanid, &i_sid))
274  {
275  mp->sub_dot1ah = 1;
276  clib_memcpy (mp->b_dmac, eth_hdr.dst_address,
277  sizeof (eth_hdr.dst_address));
278  clib_memcpy (mp->b_smac, eth_hdr.src_address,
279  sizeof (eth_hdr.src_address));
280  mp->b_vlanid = b_vlanid;
281  mp->i_sid = i_sid;
282  }
283 
285  if (tag)
286  strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
287 
288  vl_api_send_msg (rp, (u8 *) mp);
289 }
290 
291 static void
293 {
295  vnet_sw_interface_t *swif;
298 
300 
301  if (rp == 0)
302  {
303  clib_warning ("Client %d AWOL", mp->client_index);
304  return;
305  }
306 
307  u8 *filter = 0, *name = 0;
308  if (mp->name_filter_valid)
309  {
310  mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
311  filter = format (0, "%s%c", mp->name_filter, 0);
312  }
313 
314  char *strcasestr (char *, char *); /* lnx hdr file botch */
315  /* *INDENT-OFF* */
316  pool_foreach (swif, im->sw_interfaces,
317  ({
318  if (!vnet_swif_is_api_visible (swif))
319  continue;
320  vec_reset_length(name);
321  name = format (name, "%U%c", format_vnet_sw_interface_name, am->vnet_main,
322  swif, 0);
323 
324  if (filter && !strcasestr((char *) name, (char *) filter))
325  continue;
326 
327  send_sw_interface_details (am, rp, swif, name, mp->context);
328  }));
329  /* *INDENT-ON* */
330 
331  vec_free (name);
332  vec_free (filter);
333 }
334 
335 static void
338 {
339  vlib_main_t *vm = vlib_get_main ();
340  vnet_main_t *vnm = vnet_get_main ();
341  vl_api_sw_interface_add_del_address_reply_t *rmp;
342  int rv = 0;
343  u32 is_del;
344  clib_error_t *error = 0;
345 
347 
348  is_del = mp->is_add == 0;
349  vnm->api_errno = 0;
350 
351  if (mp->del_all)
353  else if (mp->is_ipv6)
354  error = ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
355  (void *) mp->address,
356  mp->address_length, is_del);
357  else
358  error = ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
359  (void *) mp->address,
360  mp->address_length, is_del);
361 
362  if (error)
363  {
364  rv = vnm->api_errno;
365  clib_error_report (error);
366  goto done;
367  }
368 
370 
371 done:
372  REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
373 }
374 
375 void stats_dslock_with_hint (int hint, int tag) __attribute__ ((weak));
376 void
377 stats_dslock_with_hint (int hint, int tag)
378 {
379 }
380 
381 void stats_dsunlock (void) __attribute__ ((weak));
382 void
384 {
385 }
386 
387 static void
389 {
390  vl_api_sw_interface_set_table_reply_t *rmp;
391  u32 sw_if_index = ntohl (mp->sw_if_index);
392  u32 table_id = ntohl (mp->vrf_id);
393  int rv = 0;
394 
396 
397  stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ );
398 
399  if (mp->is_ipv6)
400  rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, table_id, 1);
401  else
402  rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, table_id, 1);
403 
404  stats_dsunlock ();
405 
407 
408  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
409 }
410 
411 int
413  u32 sw_if_index, u32 table_id, u8 is_api)
414 {
416  u32 fib_index, mfib_index;
418  mfib_source_t msrc;
419 
420  if (is_api)
421  {
422  src = FIB_SOURCE_API;
423  msrc = MFIB_SOURCE_API;
424  }
425  else
426  {
427  src = FIB_SOURCE_CLI;
428  msrc = MFIB_SOURCE_CLI;
429  }
430 
431  /*
432  * This if table does not exist = error is what we want in the end.
433  */
434  fib_index = fib_table_find (fproto, table_id);
435  mfib_index = mfib_table_find (fproto, table_id);
436 
437  if (~0 == fib_index || ~0 == mfib_index)
438  {
439  return (VNET_API_ERROR_NO_SUCH_FIB);
440  }
441 
442  if (FIB_PROTOCOL_IP6 == fproto)
443  {
444  /*
445  * If the interface already has in IP address, then a change int
446  * VRF is not allowed. The IP address applied must first be removed.
447  * We do not do that automatically here, since VPP has no knowledge
448  * of whether those subnets are valid in the destination VRF.
449  */
450  /* *INDENT-OFF* */
452  ia, sw_if_index,
453  1 /* honor unnumbered */ ,
454  ({
455  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
456  }));
457  /* *INDENT-ON* */
458 
461 
462  /*
463  * tell those that are interested that the binding is changing.
464  */
467  cb->function (&ip6_main, cb->function_opaque,
468  sw_if_index,
469  fib_index,
470  ip6_main.fib_index_by_sw_if_index[sw_if_index]);
471 
472  if (0 == table_id)
473  {
474  /* reset back to default */
475  if (0 != ip6_main.fib_index_by_sw_if_index[sw_if_index])
477  FIB_PROTOCOL_IP6, src);
478  if (0 != ip6_main.mfib_index_by_sw_if_index[sw_if_index])
480  [sw_if_index], FIB_PROTOCOL_IP6, msrc);
481 
482  }
483  else
484  {
485  /* we need to lock the table now it's inuse */
486  fib_table_lock (fib_index, FIB_PROTOCOL_IP6, src);
487  mfib_table_lock (mfib_index, FIB_PROTOCOL_IP6, msrc);
488  }
489 
492  }
493  else
494  {
495  /*
496  * If the interface already has in IP address, then a change int
497  * VRF is not allowed. The IP address applied must first be removed.
498  * We do not do that automatically here, since VPP has no knowledge
499  * of whether those subnets are valid in the destination VRF.
500  */
501  /* *INDENT-OFF* */
503  ia, sw_if_index,
504  1 /* honor unnumbered */ ,
505  ({
506  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
507  }));
508  /* *INDENT-ON* */
509 
512 
513  /*
514  * tell those that are interested that the binding is changing.
515  */
518  cb->function (&ip4_main, cb->function_opaque,
519  sw_if_index,
520  fib_index,
521  ip4_main.fib_index_by_sw_if_index[sw_if_index]);
522 
523  if (0 == table_id)
524  {
525  /* reset back to default */
526  if (0 != ip4_main.fib_index_by_sw_if_index[sw_if_index])
528  FIB_PROTOCOL_IP4, src);
529  if (0 != ip4_main.mfib_index_by_sw_if_index[sw_if_index])
531  [sw_if_index], FIB_PROTOCOL_IP4, msrc);
532 
533  }
534  else
535  {
536  /* we need to lock the table now it's inuse */
538  table_id, src);
539 
541  table_id, msrc);
542  }
543 
546  }
547 
548  return (0);
549 }
550 
551 static void
553  u32 context, int retval, u32 vrf_id)
554 {
556 
557  mp = vl_msg_api_alloc (sizeof (*mp));
558  clib_memset (mp, 0, sizeof (*mp));
559  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_GET_TABLE_REPLY);
560  mp->context = context;
561  mp->retval = htonl (retval);
562  mp->vrf_id = htonl (vrf_id);
563 
564  vl_api_send_msg (reg, (u8 *) mp);
565 }
566 
567 static void
569 {
571  fib_table_t *fib_table = 0;
572  u32 sw_if_index = ~0;
573  u32 fib_index = ~0;
574  u32 table_id = ~0;
575  fib_protocol_t fib_proto = FIB_PROTOCOL_IP4;
576  int rv = 0;
577 
579  if (!reg)
580  return;
581 
583 
584  sw_if_index = ntohl (mp->sw_if_index);
585 
586  if (mp->is_ipv6)
587  fib_proto = FIB_PROTOCOL_IP6;
588 
589  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
590  if (fib_index != ~0)
591  {
592  fib_table = fib_table_get (fib_index, fib_proto);
593  table_id = fib_table->ft_table_id;
594  }
595 
597 
598  send_sw_interface_get_table_reply (reg, mp->context, rv, table_id);
599 }
600 
603 {
604  vl_api_sw_interface_set_unnumbered_reply_t *rmp;
605  int rv = 0;
606  vnet_main_t *vnm = vnet_get_main ();
607  u32 sw_if_index = ntohl (mp->sw_if_index);
608  u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
609 
610  /*
611  * The API message field names are backwards from
612  * the underlying data structure names.
613  * It's not worth changing them now.
614  */
615  if (!vnet_sw_interface_is_api_valid (vnm, unnumbered_sw_if_index))
616  {
617  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
618  goto done;
619  }
620 
621  /* Only check the "use loop0" field when setting the binding */
622  if (mp->is_add && !vnet_sw_interface_is_api_valid (vnm, sw_if_index))
623  {
624  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
625  goto done;
626  }
627 
628  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
629  sw_if_index, mp->is_add);
630 done:
631  REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
632 }
633 
634 static void
636  mp)
637 {
638  vl_api_sw_interface_clear_stats_reply_t *rmp;
639 
640  vnet_main_t *vnm = vnet_get_main ();
644  static vnet_main_t **my_vnet_mains;
645  int i, j, n_counters;
646  int rv = 0;
647 
648  if (mp->sw_if_index != ~0)
650 
651  vec_reset_length (my_vnet_mains);
652 
653  for (i = 0; i < vec_len (vnet_mains); i++)
654  {
655  if (vnet_mains[i])
656  vec_add1 (my_vnet_mains, vnet_mains[i]);
657  }
658 
659  if (vec_len (vnet_mains) == 0)
660  vec_add1 (my_vnet_mains, vnm);
661 
662  n_counters = vec_len (im->combined_sw_if_counters);
663 
664  for (j = 0; j < n_counters; j++)
665  {
666  for (i = 0; i < vec_len (my_vnet_mains); i++)
667  {
668  im = &my_vnet_mains[i]->interface_main;
669  cm = im->combined_sw_if_counters + j;
670  if (mp->sw_if_index == (u32) ~ 0)
672  else
673  vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
674  }
675  }
676 
677  n_counters = vec_len (im->sw_if_counters);
678 
679  for (j = 0; j < n_counters; j++)
680  {
681  for (i = 0; i < vec_len (my_vnet_mains); i++)
682  {
683  im = &my_vnet_mains[i]->interface_main;
684  sm = im->sw_if_counters + j;
685  if (mp->sw_if_index == (u32) ~ 0)
687  else
688  vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
689  }
690  }
691 
693 
694  REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
695 }
696 
697 /*
698  * Events used for sw_interface_events
699  */
701 {
708 };
709 
710 static void
713  vl_api_registration_t * vl_reg,
714  u32 sw_if_index, enum api_events events)
715 {
717 
718  mp = vl_msg_api_alloc (sizeof (*mp));
719  clib_memset (mp, 0, sizeof (*mp));
720  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_EVENT);
721  mp->sw_if_index = ntohl (sw_if_index);
722  mp->client_index = reg->client_index;
723  mp->pid = reg->client_pid;
724  mp->admin_up_down = events & API_ADMIN_UP_EVENT ? 1 : 0;
725  mp->link_up_down = events & API_LINK_STATE_UP_EVENT ? 1 : 0;
726  mp->deleted = events & API_SW_INTERFACE_DEL_EVENT ? 1 : 0;
727  vl_api_send_msg (vl_reg, (u8 *) mp);
728 }
729 
730 static uword
733 {
735  uword *event_by_sw_if_index = 0;
737  int i;
738  vl_api_registration_t *vl_reg;
739  uword event_type;
740  uword *event_data = 0;
742 
743  vam->link_state_process_up = 1;
744 
745  while (1)
746  {
748 
749  /* Batch up events */
750  while ((event_type = vlib_process_get_events (vm, &event_data)) != ~0)
751  {
752  for (i = 0; i < vec_len (event_data); i++)
753  {
754  sw_if_index = event_data[i];
755  vec_validate_init_empty (event_by_sw_if_index, sw_if_index, 0);
756  event_by_sw_if_index[sw_if_index] |= event_type;
757  }
758  vec_reset_length (event_data);
759  }
760 
761  for (i = 0; i < vec_len (event_by_sw_if_index); i++)
762  {
763  if (event_by_sw_if_index[i] == 0)
764  continue;
765 
766  /* *INDENT-OFF* */
767  pool_foreach(reg, vam->interface_events_registrations,
768  ({
769  vl_reg = vl_api_client_index_to_registration (reg->client_index);
770  if (vl_reg)
771  send_sw_interface_event (vam, reg, vl_reg, i, event_by_sw_if_index[i]);
772  }));
773  /* *INDENT-ON* */
774  }
775  vec_reset_length (event_by_sw_if_index);
776  }
777 
778  return 0;
779 }
780 
781 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
782  u32 flags);
784  u32 hw_if_index, u32 flags);
786  u32 sw_if_index,
787  u32 flags);
788 
789 /* *INDENT-OFF* */
790 VLIB_REGISTER_NODE (link_state_process_node,static) = {
791  .function = link_state_process,
792  .type = VLIB_NODE_TYPE_PROCESS,
793  .name = "vpe-link-state-process",
794 };
795 /* *INDENT-ON* */
796 
797 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
798 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
799 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (sw_interface_add_del_function);
800 
801 static clib_error_t *
802 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
803 {
805  vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
806 
807  if (vam->link_state_process_up)
808  {
809  enum api_events event =
812  link_state_process_node.index, event,
813  hi->sw_if_index);
814  }
815  return 0;
816 }
817 
818 static clib_error_t *
819 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
820 {
822 
823  /*
824  * Note: it's perfectly fair to set a subif admin up / admin down.
825  * Note the subtle distinction between this routine and the previous
826  * routine.
827  */
828  if (vam->link_state_process_up)
829  {
830  enum api_events event =
833  link_state_process_node.index, event,
834  sw_if_index);
835  }
836  return 0;
837 }
838 
839 static clib_error_t *
841 {
843 
844  if (vam->link_state_process_up)
845  {
846  enum api_events event =
849  link_state_process_node.index, event,
850  sw_if_index);
851  }
852  return 0;
853 }
854 
857 {
858  vnet_main_t *vnm = vnet_get_main ();
859  vl_api_sw_interface_tag_add_del_reply_t *rmp;
860  int rv = 0;
861  u8 *tag;
862  u32 sw_if_index = ntohl (mp->sw_if_index);
863 
865 
866  if (mp->is_add)
867  {
868  if (mp->tag[0] == 0)
869  {
870  rv = VNET_API_ERROR_INVALID_VALUE;
871  goto out;
872  }
873 
874  mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
875  tag = format (0, "%s%c", mp->tag, 0);
876  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
877  }
878  else
879  vnet_clear_sw_interface_tag (vnm, sw_if_index);
880 
882 out:
883  REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY);
884 }
885 
888 {
889  vl_api_sw_interface_set_mac_address_reply_t *rmp;
890  vnet_main_t *vnm = vnet_get_main ();
891  u32 sw_if_index = ntohl (mp->sw_if_index);
893  clib_error_t *error;
894  int rv = 0;
895 
897 
898  si = vnet_get_sw_interface (vnm, sw_if_index);
900  mp->mac_address);
901  if (error)
902  {
903  rv = VNET_API_ERROR_UNIMPLEMENTED;
904  clib_error_report (error);
905  goto out;
906  }
907 
909 out:
910  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
911 }
912 
915 {
918  vnet_main_t *vnm = vnet_get_main ();
919  u32 sw_if_index = ntohl (mp->sw_if_index);
921  ethernet_interface_t *eth_if = 0;
922  int rv = 0;
923 
925 
926  si = vnet_get_sup_sw_interface (vnm, sw_if_index);
929 
931 
933  if (!reg)
934  return;
935  rmp = vl_msg_api_alloc (sizeof (*rmp));
936  rmp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS_REPLY);
937  rmp->context = mp->context;
938  rmp->retval = htonl (rv);
939  if (!rv && eth_if)
940  memcpy (rmp->mac_address, eth_if->address, 6);
941  vl_api_send_msg (reg, (u8 *) rmp);
942 }
943 
946 {
947  vl_api_sw_interface_set_rx_mode_reply_t *rmp;
948  vnet_main_t *vnm = vnet_get_main ();
949  u32 sw_if_index = ntohl (mp->sw_if_index);
951  clib_error_t *error;
952  int rv = 0;
953 
955 
956  si = vnet_get_sw_interface (vnm, sw_if_index);
958  {
959  rv = VNET_API_ERROR_INVALID_VALUE;
960  goto bad_sw_if_index;
961  }
962 
964  mp->queue_id_valid,
965  ntohl (mp->queue_id), mp->mode);
966  if (error)
967  {
968  rv = VNET_API_ERROR_UNIMPLEMENTED;
969  clib_error_report (error);
970  goto out;
971  }
972 
974 out:
975  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
976 }
977 
978 static void
981  u32 sw_if_index, u32 worker_id,
982  u32 queue_id, u8 mode, u32 context)
983 {
985  mp = vl_msg_api_alloc (sizeof (*mp));
986  clib_memset (mp, 0, sizeof (*mp));
987 
988  mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_RX_PLACEMENT_DETAILS);
989  mp->sw_if_index = htonl (sw_if_index);
990  mp->queue_id = htonl (queue_id);
991  mp->worker_id = htonl (worker_id);
992  mp->mode = mode;
993  mp->context = context;
994 
995  vl_api_send_msg (rp, (u8 *) mp);
996 }
997 
1000 {
1001  vnet_main_t *vnm = vnet_get_main ();
1003  u32 sw_if_index = ntohl (mp->sw_if_index);
1004  vl_api_registration_t *reg;
1005 
1007  if (!reg)
1008  return;
1009 
1010  if (sw_if_index == ~0)
1011  {
1015  (u8 *) "device-input");
1016  uword si;
1017  int index = 0;
1018 
1019  /* *INDENT-OFF* */
1020  foreach_vlib_main (({
1022  ({
1023  rt = vlib_node_get_runtime_data (this_vlib_main, si);
1024  vec_foreach (dq, rt->devices_and_queues)
1025  {
1026  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm,
1027  dq->hw_if_index);
1028  send_interface_rx_placement_details (am, reg, hw->sw_if_index, index,
1029  dq->queue_id, dq->mode, mp->context);
1030  }
1031  }));
1032  index++;
1033  }));
1034  /* *INDENT-ON* */
1035  }
1036  else
1037  {
1038  int i;
1039  vnet_sw_interface_t *si;
1040 
1041  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
1042  {
1043  clib_warning ("sw_if_index %u does not exist", sw_if_index);
1044  goto bad_sw_if_index;
1045  }
1046 
1047  si = vnet_get_sw_interface (vnm, sw_if_index);
1049  {
1050  clib_warning ("interface type is not HARDWARE! P2P, PIPE and SUB"
1051  " interfaces are not supported");
1052  goto bad_sw_if_index;
1053  }
1054 
1056 
1057  for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++)
1058  {
1061  [i], i,
1062  hw->rx_mode_by_queue[i],
1063  mp->context);
1064  }
1065  }
1066 
1068 }
1069 
1072 {
1073  vl_api_sw_interface_set_rx_placement_reply_t *rmp;
1074  vnet_main_t *vnm = vnet_get_main ();
1075  u32 sw_if_index = ntohl (mp->sw_if_index);
1076  vnet_sw_interface_t *si;
1077  clib_error_t *error = 0;
1078  int rv = 0;
1079 
1080  VALIDATE_SW_IF_INDEX (mp);
1081 
1082  si = vnet_get_sw_interface (vnm, sw_if_index);
1084  {
1085  rv = VNET_API_ERROR_INVALID_VALUE;
1086  goto bad_sw_if_index;
1087  }
1088 
1090  ntohl (mp->queue_id),
1091  ntohl (mp->worker_id), mp->is_main);
1092  if (error)
1093  {
1094  rv = VNET_API_ERROR_UNIMPLEMENTED;
1095  clib_error_report (error);
1096  goto out;
1097  }
1098 
1100 out:
1101  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_PLACEMENT_REPLY);
1102 }
1103 
1104 static void
1106 {
1108  vnet_main_t *vnm = vnet_get_main ();
1109  u32 sw_if_index = (u32) ~ 0;
1111  int rv = 0;
1112  u32 id;
1113  vnet_sw_interface_t template;
1114  uword *p;
1116  u64 sup_and_sub_key;
1117  vl_api_registration_t *reg;
1118  clib_error_t *error;
1119 
1120  VALIDATE_SW_IF_INDEX (mp);
1121 
1122  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1123 
1125  {
1126  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1127  goto out;
1128  }
1129 
1130  id = ntohl (mp->vlan_id);
1131  if (id == 0 || id > 4095)
1132  {
1133  rv = VNET_API_ERROR_INVALID_VLAN;
1134  goto out;
1135  }
1136 
1137  sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1138 
1139  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1140  if (p)
1141  {
1142  rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1143  goto out;
1144  }
1145 
1146  clib_memset (&template, 0, sizeof (template));
1147  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1148  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1149  template.sup_sw_if_index = hi->sw_if_index;
1150  template.sub.id = id;
1151  template.sub.eth.raw_flags = 0;
1152  template.sub.eth.flags.one_tag = 1;
1153  template.sub.eth.outer_vlan_id = id;
1154  template.sub.eth.flags.exact_match = 1;
1155 
1156  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1157  if (error)
1158  {
1159  clib_error_report (error);
1160  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1161  goto out;
1162  }
1163 
1164  u64 *kp = clib_mem_alloc (sizeof (*kp));
1165  *kp = sup_and_sub_key;
1166 
1167  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1168  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1169 
1171 
1172 out:
1174  if (!reg)
1175  return;
1176 
1177  rmp = vl_msg_api_alloc (sizeof (*rmp));
1178  rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
1179  rmp->context = mp->context;
1180  rmp->retval = htonl (rv);
1181  rmp->sw_if_index = htonl (sw_if_index);
1182  vl_api_send_msg (reg, (u8 *) rmp);
1183 }
1184 
1185 static void
1187 {
1189  vnet_main_t *vnm = vnet_get_main ();
1190  u32 sw_if_index = ~0;
1191  int rv = 0;
1192  u32 sub_id;
1193  vnet_sw_interface_t *si;
1195  vnet_sw_interface_t template;
1196  uword *p;
1198  u64 sup_and_sub_key;
1199  clib_error_t *error;
1200 
1201  VALIDATE_SW_IF_INDEX (mp);
1202 
1203  si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1204  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1205 
1207  {
1208  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1209  goto out;
1210  }
1211 
1212  sw_if_index = si->sw_if_index;
1213  sub_id = ntohl (mp->sub_id);
1214 
1215  sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1216 
1217  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1218  if (p)
1219  {
1220  if (CLIB_DEBUG > 0)
1221  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1222  sw_if_index, sub_id);
1223  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1224  goto out;
1225  }
1226 
1227  clib_memset (&template, 0, sizeof (template));
1228  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1229  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1230  template.sup_sw_if_index = sw_if_index;
1231  template.sub.id = sub_id;
1232  template.sub.eth.flags.no_tags = mp->no_tags;
1233  template.sub.eth.flags.one_tag = mp->one_tag;
1234  template.sub.eth.flags.two_tags = mp->two_tags;
1235  template.sub.eth.flags.dot1ad = mp->dot1ad;
1236  template.sub.eth.flags.exact_match = mp->exact_match;
1237  template.sub.eth.flags.default_sub = mp->default_sub;
1238  template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1239  template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1240  template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1241  template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1242 
1243  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1244  if (error)
1245  {
1246  clib_error_report (error);
1247  rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1248  goto out;
1249  }
1250 
1251  u64 *kp = clib_mem_alloc (sizeof (*kp));
1252  *kp = sup_and_sub_key;
1253 
1254  hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1255  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1256 
1258 
1259 out:
1260 
1261  /* *INDENT-OFF* */
1262  REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1263  ({
1264  rmp->sw_if_index = ntohl(sw_if_index);
1265  }));
1266  /* *INDENT-ON* */
1267 }
1268 
1269 static void
1271 {
1272  vl_api_delete_subif_reply_t *rmp;
1273  int rv;
1274 
1275  rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
1276 
1277  REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
1278 }
1279 
1280 static void
1282  mp)
1283 {
1284  vl_api_interface_name_renumber_reply_t *rmp;
1285  int rv = 0;
1286 
1287  VALIDATE_SW_IF_INDEX (mp);
1288 
1290  (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
1291 
1293 
1294  REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
1295 }
1296 
1297 static void
1299 {
1301  u32 sw_if_index;
1302  int rv;
1303 
1304  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address, 0, 0);
1305 
1306  /* *INDENT-OFF* */
1307  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
1308  ({
1309  rmp->sw_if_index = ntohl (sw_if_index);
1310  }));
1311  /* *INDENT-ON* */
1312 }
1313 
1316 {
1318  u32 sw_if_index;
1319  u8 is_specified = mp->is_specified;
1320  u32 user_instance = ntohl (mp->user_instance);
1321  int rv;
1322 
1323  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address,
1324  is_specified, user_instance);
1325 
1326  /* *INDENT-OFF* */
1327  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_INSTANCE_REPLY,
1328  ({
1329  rmp->sw_if_index = ntohl (sw_if_index);
1330  }));
1331  /* *INDENT-ON* */
1332 }
1333 
1334 static void
1336 {
1337  vl_api_delete_loopback_reply_t *rmp;
1338  u32 sw_if_index;
1339  int rv;
1340 
1341  sw_if_index = ntohl (mp->sw_if_index);
1342  rv = vnet_delete_loopback_interface (sw_if_index);
1343 
1344  REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
1345 }
1346 
1347 static void
1350 {
1351  vl_api_collect_detailed_interface_stats_reply_t *rmp;
1352  int rv = 0;
1353 
1354  rv =
1356  mp->enable_disable);
1357 
1358  REPLY_MACRO (VL_API_COLLECT_DETAILED_INTERFACE_STATS_REPLY);
1359 }
1360 
1361 /*
1362  * vpe_api_hookup
1363  * Add vpe's API message handlers to the table.
1364  * vlib has already mapped shared memory and
1365  * added the client registration handlers.
1366  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1367  */
1368 #define vl_msg_name_crc_list
1369 #include <vnet/interface.api.h>
1370 #undef vl_msg_name_crc_list
1371 
1372 static void
1374 {
1375 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1376  foreach_vl_msg_name_crc_interface;
1377 #undef _
1378 }
1379 
1380 pub_sub_handler (interface_events, INTERFACE_EVENTS);
1381 
1382 static clib_error_t *
1384 {
1385  api_main_t *am = &api_main;
1386 
1387 #define _(N,n) \
1388  vl_msg_api_set_handlers(VL_API_##N, #n, \
1389  vl_api_##n##_t_handler, \
1390  vl_noop_handler, \
1391  vl_api_##n##_t_endian, \
1392  vl_api_##n##_t_print, \
1393  sizeof(vl_api_##n##_t), 1);
1395 #undef _
1396 
1397  /* Mark these APIs as mp safe */
1398  am->is_mp_safe[VL_API_SW_INTERFACE_DUMP] = 1;
1399  am->is_mp_safe[VL_API_SW_INTERFACE_DETAILS] = 1;
1400  am->is_mp_safe[VL_API_SW_INTERFACE_TAG_ADD_DEL] = 1;
1401 
1402  /* Do not replay VL_API_SW_INTERFACE_DUMP messages */
1403  am->api_trace_cfg[VL_API_SW_INTERFACE_DUMP].replay_enable = 0;
1404 
1405  /*
1406  * Set up the (msg_name, crc, message-id) table
1407  */
1409 
1410  return 0;
1411 }
1412 
1414 
1415 /*
1416  * fd.io coding-style-patch-verification: ON
1417  *
1418  * Local Variables:
1419  * eval: (c-set-style "gnu")
1420  * End:
1421  */
static void vl_api_delete_subif_t_handler(vl_api_delete_subif_t *mp)
uword * sibling_bitmap
Definition: node.h:339
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:182
u32 sw_if_index
Definition: ipsec_gre.api:37
vmrglw vmrglh hi
u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, mfib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:562
#define hash_set(h, key, value)
Definition: hash.h:255
u32 flags
Definition: vhost_user.h:115
ip4_table_bind_function_t * function
Definition: ip4.h:83
vnet_main_t * vnet_main
#define CLIB_UNUSED(x)
Definition: clib.h:82
Enable or disable detailed interface stats.
Definition: interface.api:588
clib_error_t * set_hw_interface_rx_placement(u32 hw_if_index, u32 queue_id, u32 thread_index, u8 is_main)
void vnet_sw_interface_ip_directed_broadcast(vnet_main_t *vnm, u32 sw_if_index, u8 enable)
Definition: interface.c:675
Get interface&#39;s MAC address.
Definition: interface.api:346
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:593
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip6.h:197
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static void vl_api_interface_name_renumber_t_handler(vl_api_interface_name_renumber_t *mp)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
void stats_dsunlock(void)
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(link_up_down_function)
ethernet_main_t * ethernet_get_main(vlib_main_t *vm)
Definition: init.c:117
static clib_error_t * sw_interface_add_del_function(vnet_main_t *vm, u32 sw_if_index, u32 flags)
Set flags on the interface.
Definition: interface.api:33
vnet_interface_main_t interface_main
Definition: vnet.h:56
static void vl_api_sw_interface_add_del_address_t_handler(vl_api_sw_interface_add_del_address_t *mp)
unsigned long u64
Definition: types.h:89
#define REPLY_MACRO2(t, body)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:956
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
u8 src_address[6]
Definition: packet.h:56
Set an interface&#39;s rx-placement Rx-Queue placement on specific thread is operational for only hardwar...
Definition: interface.api:396
u32 * input_node_thread_index_by_queue
Definition: interface.h:559
vnet_main_t ** vnet_mains
Definition: misc.c:44
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
From the CLI.
Definition: fib_entry.h:78
static void vl_api_delete_loopback_t_handler(vl_api_delete_loopback_t *mp)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1355
static void vnet_clear_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
static void send_sw_interface_event(vpe_api_main_t *am, vpe_client_registration_t *reg, vl_api_registration_t *vl_reg, u32 sw_if_index, enum api_events events)
int i
VLIB_API_INIT_FUNCTION(interface_api_hookup)
#define hash_set_mem(h, key, value)
Definition: hash.h:275
ip_lookup_main_t lookup_main
Definition: ip4.h:98
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:542
vlib_main_t * vlib_main
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:112
Set IP4 directed broadcast The directed broadcast enabled a packet sent to the interface&#39;s subnet add...
Definition: interface.api:72
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static void vl_api_sw_interface_set_unnumbered_t_handler(vl_api_sw_interface_set_unnumbered_t *mp)
static void vl_api_sw_interface_set_rx_placement_t_handler(vl_api_sw_interface_set_rx_placement_t *mp)
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
uword * dq_runtime_index_by_queue
Definition: interface.h:566
void * vl_msg_api_alloc(int nbytes)
static void vl_api_sw_interface_dump_t_handler(vl_api_sw_interface_dump_t *mp)
unsigned char u8
Definition: types.h:56
trace_cfg_t * api_trace_cfg
Current trace configuration.
Definition: api_common.h:249
static void send_interface_rx_placement_details(vpe_api_main_t *am, vl_api_registration_t *rp, u32 sw_if_index, u32 worker_id, u32 queue_id, u8 mode, u32 context)
#define VNET_HW_INTERFACE_FLAG_DUPLEX_MASK
Definition: interface.h:482
static clib_error_t * interface_api_hookup(vlib_main_t *vm)
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static uword link_state_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
#define clib_memcpy(d, s, n)
Definition: string.h:180
int ip_table_bind(fib_protocol_t fproto, u32 sw_if_index, u32 table_id, u8 is_api)
enum mfib_source_t_ mfib_source_t
Possible [control plane] sources of MFIB entries.
ethernet_main_t ethernet_main
Definition: init.c:45
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:115
Set an interface&#39;s rx-mode.
Definition: interface.api:375
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:60
Clear interface statistics.
Definition: interface.api:304
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:516
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:824
u8 dst_address[6]
Definition: packet.h:55
Reply for the vlan subinterface create request.
Definition: interface.api:499
vnet_hw_interface_flags_t flags
Definition: interface.h:494
static void vl_api_sw_interface_rx_placement_dump_t_handler(vl_api_sw_interface_rx_placement_dump_t *mp)
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static void vl_api_hw_interface_set_mtu_t_handler(vl_api_hw_interface_set_mtu_t *mp)
Get VRF id assigned to interface.
Definition: interface.api:264
u32 mtu[VNET_N_MTU]
Definition: interface.h:701
unsigned int u32
Definition: types.h:88
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1064
A collection of simple counters.
Definition: counter.h:57
void vnet_sw_interface_set_protocol_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu[])
Definition: interface.c:654
u32 max_supported_packet_bytes
Definition: interface.h:533
struct vnet_sub_interface_t::@208::@209::@211 flags
clib_error_t * ip4_add_del_interface_address(vlib_main_t *vm, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 is_del)
Definition: ip4_forward.c:660
vnet_api_error_t api_errno
Definition: vnet.h:78
static clib_error_t * link_up_down_function(vnet_main_t *vm, u32 hw_if_index, u32 flags)
#define VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT
Definition: interface.h:480
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:285
vnet_sub_interface_t sub
Definition: interface.h:704
static void vl_api_sw_interface_get_table_t_handler(vl_api_sw_interface_get_table_t *mp)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:934
enum fib_source_t_ fib_source_t
The different sources that can create a route.
void mfib_table_unlock(u32 fib_index, fib_protocol_t proto, mfib_source_t source)
Take a reference counting lock on the table.
Definition: mfib_table.c:653
static void send_sw_interface_get_table_reply(vl_api_registration_t *reg, u32 context, int retval, u32 vrf_id)
Set interface L3 MTU.
Definition: interface.api:57
int replay_enable
This message can be replayed.
Definition: api_common.h:83
unsigned short u16
Definition: types.h:57
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:818
static void vl_api_sw_interface_set_mac_address_t_handler(vl_api_sw_interface_set_mac_address_t *mp)
ip6_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip6.h:218
Reply to get_sw_interface_vrf.
Definition: interface.api:276
#define REPLY_MACRO(t)
vnet_sw_interface_flags_t flags
Definition: interface.h:684
clib_error_t * set_hw_interface_change_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u8 queue_id_valid, u32 queue_id, vnet_hw_interface_rx_mode mode)
static void vl_api_create_loopback_t_handler(vl_api_create_loopback_t *mp)
Create loopback interface instance response.
Definition: interface.api:562
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:823
void mfib_table_lock(u32 fib_index, fib_protocol_t proto, mfib_source_t source)
Release a reference counting lock on the table.
Definition: mfib_table.c:682
void vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1475
void ip_del_all_interface_addresses(vlib_main_t *vm, u32 sw_if_index)
Definition: ip46_cli.c:82
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
#define foreach_vlib_main(body)
Definition: threads.h:235
Set or delete one or all ip addresses on a specified interface.
Definition: interface.api:231
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1237
u8 name[64]
Definition: memclnt.api:152
vnet_hw_interface_class_t ethernet_hw_interface_class
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:202
static void setup_message_id_table(api_main_t *am)
int vnet_create_loopback_interface(u32 *sw_if_indexp, u8 *mac_address, u8 is_specified, u32 user_instance)
Definition: interface.c:735
An API client registration, only in vpp/vlib.
Definition: api_common.h:45
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:553
#define BAD_SW_IF_INDEX_LABEL
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
static void vl_api_sw_interface_set_flags_t_handler(vl_api_sw_interface_set_flags_t *mp)
Definition: interface_api.c:80
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
struct vnet_sub_interface_t::@208 eth
void stats_dslock_with_hint(int hint, int tag)
show the interface&#39;s queue - thread placement This api is used to display the interface and queue wor...
Definition: interface.api:434
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:916
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
int vnet_delete_loopback_interface(u32 sw_if_index)
Definition: interface.c:896
static clib_error_t * admin_up_down_function(vnet_main_t *vm, u32 hw_if_index, u32 flags)
u32 context
Definition: ipsec_gre.api:33
#define clib_warning(format, args...)
Definition: error.h:59
Request all or filtered subset of sw_interface_details.
Definition: interface.api:213
static void vl_api_create_loopback_instance_t_handler(vl_api_create_loopback_instance_t *mp)
Delete sub interface request.
Definition: interface.api:511
#define ARRAY_LEN(x)
Definition: clib.h:62
static void send_sw_interface_details(vpe_api_main_t *am, vl_api_registration_t *rp, vnet_sw_interface_t *swif, u8 *interface_name, u32 context)
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
#define foreach_vpe_api_msg
Definition: interface_api.c:51
Delete loopback interface request.
Definition: interface.api:574
vl_api_vxlan_gbp_api_tunnel_mode_t mode
Definition: vxlan_gbp.api:44
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(admin_up_down_function)
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
Definition: fib_table.c:1257
foreach_registration_hash u8 link_state_process_up
#define ASSERT(truth)
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(sw_interface_add_del_function)
Reply for get interface&#39;s MAC address request.
Definition: interface.api:358
ip6_main_t ip6_main
Definition: ip6_forward.c:2688
ip_lookup_main_t lookup_main
Definition: ip6.h:179
static void vnet_set_sw_interface_tag(vnet_main_t *vnm, u8 *tag, u32 sw_if_index)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1123
static void vl_api_sw_interface_tag_add_del_t_handler(vl_api_sw_interface_tag_add_del_t *mp)
#define clib_error_report(e)
Definition: error.h:113
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:139
static u8 * vnet_get_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
From the control plane API.
Definition: fib_entry.h:74
static void vl_api_sw_interface_clear_stats_t_handler(vl_api_sw_interface_clear_stats_t *mp)
static void * clib_mem_alloc(uword size)
Definition: mem.h:132
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
Interface Event generated by want_interface_events.
Definition: interface.api:89
static void vl_api_sw_interface_set_mtu_t_handler(vl_api_sw_interface_set_mtu_t *mp)
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip4.h:133
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
static void vl_api_sw_interface_set_rx_mode_t_handler(vl_api_sw_interface_set_rx_mode_t *mp)
void vnet_hw_interface_set_mtu(vnet_main_t *vnm, u32 hw_if_index, u32 mtu)
Definition: interface.c:702
static void vl_api_create_subif_t_handler(vl_api_create_subif_t *mp)
Create loopback interface instance request.
Definition: interface.api:548
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:886
api_events
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Set interface physical MTU.
Definition: interface.api:48
u32 mfib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:504
u64 uword
Definition: types.h:112
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:815
Create loopback interface request.
Definition: interface.api:522
ip6_table_bind_function_t * function
Definition: ip6.h:114
Set unnumbered interface add / del request.
Definition: interface.api:290
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
A collection of combined counters.
Definition: counter.h:188
Create a new subinterface with the given vlan id.
Definition: interface.api:486
int vnet_sw_interface_stats_collect_enable_disable(u32 sw_if_index, u8 enable)
Create loopback interface response.
Definition: interface.api:534
#define hash_get_mem(h, key)
Definition: hash.h:269
static void vl_api_sw_interface_set_ip_directed_broadcast_t_handler(vl_api_sw_interface_set_ip_directed_broadcast_t *mp)
dump the rx queue placement of interface(s)
Definition: interface.api:412
u32 l2vtr_get(vlib_main_t *vlib_main, vnet_main_t *vnet_main, u32 sw_if_index, u32 *vtr_op, u32 *push_dot1q, u32 *vtr_tag1, u32 *vtr_tag2)
Get vtag tag rewrite on the given interface.
Definition: l2_vtr.c:347
Set an interface&#39;s MAC address.
Definition: interface.api:333
u8 * is_mp_safe
Message is mp safe vector.
Definition: api_common.h:225
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:43
vnet_sw_interface_type_t type
Definition: interface.h:682
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:905
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:513
pub_sub_handler(interface_events, INTERFACE_EVENTS)
#define vec_foreach(var, vec)
Vector iterator.
static void vl_api_create_vlan_subif_t_handler(vl_api_create_vlan_subif_t *mp)
static void vl_api_collect_detailed_interface_stats_t_handler(vl_api_collect_detailed_interface_stats_t *mp)
clib_error_t * ip6_add_del_interface_address(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *address, u32 address_length, u32 is_del)
Definition: ip6_forward.c:197
u32 id
Definition: udp.api:45
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, const u8 *mac_address)
Definition: interface.c:1466
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:566
Interface details structure (fix this)
Definition: interface.api:142
static void vl_api_sw_interface_set_table_t_handler(vl_api_sw_interface_set_table_t *mp)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
Set / clear software interface tag.
Definition: interface.api:318
ethernet_interface_t * interfaces
Definition: ethernet.h:272
Associate the specified interface with a fib table.
Definition: interface.api:250
static void vl_api_sw_interface_get_mac_address_t_handler(vl_api_sw_interface_get_mac_address_t *mp)
api_main_t api_main
Definition: api_shared.c:35
u32 * fib_index_by_sw_if_index
Definition: ip6.h:194
u32 l2pbb_get(vlib_main_t *vlib_main, vnet_main_t *vnet_main, u32 sw_if_index, u32 *vtr_op, u16 *outer_tag, ethernet_header_t *eth_hdr, u16 *b_vlanid, u32 *i_sid)
Get pbb tag rewrite on the given interface.
Definition: l2_vtr.c:686
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:69