FD.io VPP  v19.08-27-gf4dcae4
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 
244  /* vlan tag rewrite data */
245  u32 vtr_op = L2_VTR_DISABLED;
246  u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
247 
248  if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
249  &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
250  {
251  // error - default to disabled
252  mp->vtr_op = ntohl (L2_VTR_DISABLED);
253  clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
254  swif->sw_if_index);
255  }
256  else
257  {
258  mp->vtr_op = ntohl (vtr_op);
259  mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
260  mp->vtr_tag1 = ntohl (vtr_tag1);
261  mp->vtr_tag2 = ntohl (vtr_tag2);
262  }
263 
264  /* pbb tag rewrite data */
265  ethernet_header_t eth_hdr;
266  u32 pbb_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  &pbb_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;
299 
301 
302  if (rp == 0)
303  {
304  clib_warning ("Client %d AWOL", mp->client_index);
305  return;
306  }
307 
308  u8 *filter = 0, *name = 0;
309  sw_if_index = ntohl (mp->sw_if_index);
310 
311  if (!mp->name_filter_valid && sw_if_index != ~0 && sw_if_index != 0)
312  {
313  /* is it a valid sw_if_index? */
314  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
315  return;
316 
317  swif = vec_elt_at_index (im->sw_interfaces, sw_if_index);
318 
320  name =
322  swif, 0);
323  send_sw_interface_details (am, rp, swif, name, mp->context);
324  vec_free (name);
325  return;
326  }
327 
328  if (mp->name_filter_valid)
329  {
330  filter =
331  format (0, ".*%s", vl_api_string_len (&mp->name_filter),
333  }
334 
335  char *strcasestr (char *, char *); /* lnx hdr file botch */
336  /* *INDENT-OFF* */
337  pool_foreach (swif, im->sw_interfaces,
338  ({
339  if (!vnet_swif_is_api_visible (swif))
340  continue;
341  vec_reset_length(name);
342  name = format (name, "%U%c", format_vnet_sw_interface_name, am->vnet_main,
343  swif, 0);
344 
345  if (filter && !strcasestr((char *) name, (char *) filter))
346  continue;
347 
348  send_sw_interface_details (am, rp, swif, name, mp->context);
349  }));
350  /* *INDENT-ON* */
351 
352  vec_free (name);
353  vec_free (filter);
354 }
355 
356 static void
359 {
360  vlib_main_t *vm = vlib_get_main ();
361  vnet_main_t *vnm = vnet_get_main ();
362  vl_api_sw_interface_add_del_address_reply_t *rmp;
363  int rv = 0;
364  u32 is_del;
365  clib_error_t *error = 0;
366 
368 
369  is_del = mp->is_add == 0;
370  vnm->api_errno = 0;
371 
372  if (mp->del_all)
374  else if (mp->is_ipv6)
375  error = ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
376  (void *) mp->address,
377  mp->address_length, is_del);
378  else
379  error = ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
380  (void *) mp->address,
381  mp->address_length, is_del);
382 
383  if (error)
384  {
385  rv = vnm->api_errno;
386  clib_error_report (error);
387  goto done;
388  }
389 
391 
392 done:
393  REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
394 }
395 
396 static void
398 {
399  vl_api_sw_interface_set_table_reply_t *rmp;
400  u32 sw_if_index = ntohl (mp->sw_if_index);
401  u32 table_id = ntohl (mp->vrf_id);
402  int rv = 0;
403 
405 
406  if (mp->is_ipv6)
407  rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, table_id, 1);
408  else
409  rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, table_id, 1);
410 
412 
413  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
414 }
415 
416 int
418  u32 sw_if_index, u32 table_id, u8 is_api)
419 {
421  u32 fib_index, mfib_index;
423  mfib_source_t msrc;
424 
425  if (is_api)
426  {
427  src = FIB_SOURCE_API;
428  msrc = MFIB_SOURCE_API;
429  }
430  else
431  {
432  src = FIB_SOURCE_CLI;
433  msrc = MFIB_SOURCE_CLI;
434  }
435 
436  /*
437  * This if table does not exist = error is what we want in the end.
438  */
439  fib_index = fib_table_find (fproto, table_id);
440  mfib_index = mfib_table_find (fproto, table_id);
441 
442  if (~0 == fib_index || ~0 == mfib_index)
443  {
444  return (VNET_API_ERROR_NO_SUCH_FIB);
445  }
446 
447  if (FIB_PROTOCOL_IP6 == fproto)
448  {
449  /*
450  * If the interface already has in IP address, then a change int
451  * VRF is not allowed. The IP address applied must first be removed.
452  * We do not do that automatically here, since VPP has no knowledge
453  * of whether those subnets are valid in the destination VRF.
454  */
455  /* *INDENT-OFF* */
457  ia, sw_if_index,
458  1 /* honor unnumbered */ ,
459  ({
460  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
461  }));
462  /* *INDENT-ON* */
463 
466 
467  /*
468  * tell those that are interested that the binding is changing.
469  */
472  cb->function (&ip6_main, cb->function_opaque,
473  sw_if_index,
474  fib_index,
475  ip6_main.fib_index_by_sw_if_index[sw_if_index]);
476 
477  if (0 == table_id)
478  {
479  /* reset back to default */
480  if (0 != ip6_main.fib_index_by_sw_if_index[sw_if_index])
482  FIB_PROTOCOL_IP6, src);
483  if (0 != ip6_main.mfib_index_by_sw_if_index[sw_if_index])
485  [sw_if_index], FIB_PROTOCOL_IP6, msrc);
486 
487  }
488  else
489  {
490  /* we need to lock the table now it's inuse */
491  fib_table_lock (fib_index, FIB_PROTOCOL_IP6, src);
492  mfib_table_lock (mfib_index, FIB_PROTOCOL_IP6, msrc);
493  }
494 
497  }
498  else
499  {
500  /*
501  * If the interface already has in IP address, then a change int
502  * VRF is not allowed. The IP address applied must first be removed.
503  * We do not do that automatically here, since VPP has no knowledge
504  * of whether those subnets are valid in the destination VRF.
505  */
506  /* *INDENT-OFF* */
508  ia, sw_if_index,
509  1 /* honor unnumbered */ ,
510  ({
511  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
512  }));
513  /* *INDENT-ON* */
514 
517 
518  /*
519  * tell those that are interested that the binding is changing.
520  */
523  cb->function (&ip4_main, cb->function_opaque,
524  sw_if_index,
525  fib_index,
526  ip4_main.fib_index_by_sw_if_index[sw_if_index]);
527 
528  if (0 == table_id)
529  {
530  /* reset back to default */
531  if (0 != ip4_main.fib_index_by_sw_if_index[sw_if_index])
533  FIB_PROTOCOL_IP4, src);
534  if (0 != ip4_main.mfib_index_by_sw_if_index[sw_if_index])
536  [sw_if_index], FIB_PROTOCOL_IP4, msrc);
537 
538  }
539  else
540  {
541  /* we need to lock the table now it's inuse */
543  table_id, src);
544 
546  table_id, msrc);
547  }
548 
551  }
552 
553  return (0);
554 }
555 
556 static void
558  u32 context, int retval, u32 vrf_id)
559 {
561 
562  mp = vl_msg_api_alloc (sizeof (*mp));
563  clib_memset (mp, 0, sizeof (*mp));
564  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_GET_TABLE_REPLY);
565  mp->context = context;
566  mp->retval = htonl (retval);
567  mp->vrf_id = htonl (vrf_id);
568 
569  vl_api_send_msg (reg, (u8 *) mp);
570 }
571 
572 static void
574 {
576  fib_table_t *fib_table = 0;
577  u32 sw_if_index = ~0;
578  u32 fib_index = ~0;
579  u32 table_id = ~0;
580  fib_protocol_t fib_proto = FIB_PROTOCOL_IP4;
581  int rv = 0;
582 
584  if (!reg)
585  return;
586 
588 
589  sw_if_index = ntohl (mp->sw_if_index);
590 
591  if (mp->is_ipv6)
592  fib_proto = FIB_PROTOCOL_IP6;
593 
594  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
595  if (fib_index != ~0)
596  {
597  fib_table = fib_table_get (fib_index, fib_proto);
598  table_id = fib_table->ft_table_id;
599  }
600 
602 
603  send_sw_interface_get_table_reply (reg, mp->context, rv, table_id);
604 }
605 
608 {
609  vl_api_sw_interface_set_unnumbered_reply_t *rmp;
610  int rv = 0;
611  vnet_main_t *vnm = vnet_get_main ();
612  u32 sw_if_index = ntohl (mp->sw_if_index);
613  u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
614 
615  /*
616  * The API message field names are backwards from
617  * the underlying data structure names.
618  * It's not worth changing them now.
619  */
620  if (!vnet_sw_interface_is_api_valid (vnm, unnumbered_sw_if_index))
621  {
622  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
623  goto done;
624  }
625 
626  /* Only check the "use loop0" field when setting the binding */
627  if (mp->is_add && !vnet_sw_interface_is_api_valid (vnm, sw_if_index))
628  {
629  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
630  goto done;
631  }
632 
633  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
634  sw_if_index, mp->is_add);
635 done:
636  REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
637 }
638 
639 static void
641  mp)
642 {
643  vl_api_sw_interface_clear_stats_reply_t *rmp;
644 
645  vnet_main_t *vnm = vnet_get_main ();
649  int j, n_counters;
650  int rv = 0;
651 
652  if (mp->sw_if_index != ~0)
654 
655  n_counters = vec_len (im->combined_sw_if_counters);
656 
657  for (j = 0; j < n_counters; j++)
658  {
659  im = &vnm->interface_main;
660  cm = im->combined_sw_if_counters + j;
661  if (mp->sw_if_index == (u32) ~ 0)
663  else
664  vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
665  }
666 
667  n_counters = vec_len (im->sw_if_counters);
668 
669  for (j = 0; j < n_counters; j++)
670  {
671  im = &vnm->interface_main;
672  sm = im->sw_if_counters + j;
673  if (mp->sw_if_index == (u32) ~ 0)
675  else
676  vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
677  }
678 
680 
681  REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
682 }
683 
684 /*
685  * Events used for sw_interface_events
686  */
688 {
695 };
696 
697 static void
700  vl_api_registration_t * vl_reg,
701  u32 sw_if_index, enum api_events events)
702 {
704 
705  mp = vl_msg_api_alloc (sizeof (*mp));
706  clib_memset (mp, 0, sizeof (*mp));
707  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_EVENT);
708  mp->sw_if_index = ntohl (sw_if_index);
709  mp->client_index = reg->client_index;
710  mp->pid = reg->client_pid;
711  mp->admin_up_down = events & API_ADMIN_UP_EVENT ? 1 : 0;
712  mp->link_up_down = events & API_LINK_STATE_UP_EVENT ? 1 : 0;
713  mp->deleted = events & API_SW_INTERFACE_DEL_EVENT ? 1 : 0;
714  vl_api_send_msg (vl_reg, (u8 *) mp);
715 }
716 
717 static uword
720 {
722  uword *event_by_sw_if_index = 0;
724  int i;
725  vl_api_registration_t *vl_reg;
726  uword event_type;
727  uword *event_data = 0;
729 
730  vam->link_state_process_up = 1;
731 
732  while (1)
733  {
735 
736  /* Batch up events */
737  while ((event_type = vlib_process_get_events (vm, &event_data)) != ~0)
738  {
739  for (i = 0; i < vec_len (event_data); i++)
740  {
741  sw_if_index = event_data[i];
742  vec_validate_init_empty (event_by_sw_if_index, sw_if_index, 0);
743  event_by_sw_if_index[sw_if_index] |= event_type;
744  }
745  vec_reset_length (event_data);
746  }
747 
748  for (i = 0; i < vec_len (event_by_sw_if_index); i++)
749  {
750  if (event_by_sw_if_index[i] == 0)
751  continue;
752 
753  /* *INDENT-OFF* */
754  pool_foreach(reg, vam->interface_events_registrations,
755  ({
756  vl_reg = vl_api_client_index_to_registration (reg->client_index);
757  if (vl_reg)
758  send_sw_interface_event (vam, reg, vl_reg, i, event_by_sw_if_index[i]);
759  }));
760  /* *INDENT-ON* */
761  }
762  vec_reset_length (event_by_sw_if_index);
763  }
764 
765  return 0;
766 }
767 
768 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
769  u32 flags);
771  u32 hw_if_index, u32 flags);
773  u32 sw_if_index,
774  u32 flags);
775 
776 /* *INDENT-OFF* */
777 VLIB_REGISTER_NODE (link_state_process_node,static) = {
778  .function = link_state_process,
779  .type = VLIB_NODE_TYPE_PROCESS,
780  .name = "vpe-link-state-process",
781 };
782 /* *INDENT-ON* */
783 
784 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
785 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
786 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (sw_interface_add_del_function);
787 
788 static clib_error_t *
789 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
790 {
792  vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
793 
794  if (vam->link_state_process_up)
795  {
796  enum api_events event =
799  link_state_process_node.index, event,
800  hi->sw_if_index);
801  }
802  return 0;
803 }
804 
805 static clib_error_t *
806 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
807 {
809 
810  /*
811  * Note: it's perfectly fair to set a subif admin up / admin down.
812  * Note the subtle distinction between this routine and the previous
813  * routine.
814  */
815  if (vam->link_state_process_up)
816  {
817  enum api_events event =
820  link_state_process_node.index, event,
821  sw_if_index);
822  }
823  return 0;
824 }
825 
826 static clib_error_t *
828 {
830 
831  if (vam->link_state_process_up)
832  {
833  enum api_events event =
836  link_state_process_node.index, event,
837  sw_if_index);
838  }
839  return 0;
840 }
841 
844 {
845  vnet_main_t *vnm = vnet_get_main ();
846  vl_api_sw_interface_tag_add_del_reply_t *rmp;
847  int rv = 0;
848  u8 *tag;
849  u32 sw_if_index = ntohl (mp->sw_if_index);
850 
852 
853  if (mp->is_add)
854  {
855  if (mp->tag[0] == 0)
856  {
857  rv = VNET_API_ERROR_INVALID_VALUE;
858  goto out;
859  }
860 
861  mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
862  tag = format (0, "%s%c", mp->tag, 0);
863  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
864  }
865  else
866  vnet_clear_sw_interface_tag (vnm, sw_if_index);
867 
869 out:
870  REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY);
871 }
872 
875 {
876  vl_api_sw_interface_set_mac_address_reply_t *rmp;
877  vnet_main_t *vnm = vnet_get_main ();
878  u32 sw_if_index = ntohl (mp->sw_if_index);
880  clib_error_t *error;
881  int rv = 0;
882 
884 
885  si = vnet_get_sw_interface (vnm, sw_if_index);
887  mp->mac_address);
888  if (error)
889  {
890  rv = VNET_API_ERROR_UNIMPLEMENTED;
891  clib_error_report (error);
892  goto out;
893  }
894 
896 out:
897  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
898 }
899 
902 {
905  vnet_main_t *vnm = vnet_get_main ();
906  u32 sw_if_index = ntohl (mp->sw_if_index);
908  ethernet_interface_t *eth_if = 0;
909  int rv = 0;
910 
912 
913  si = vnet_get_sup_sw_interface (vnm, sw_if_index);
916 
918 
920  if (!reg)
921  return;
922  rmp = vl_msg_api_alloc (sizeof (*rmp));
923  rmp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS_REPLY);
924  rmp->context = mp->context;
925  rmp->retval = htonl (rv);
926  if (!rv && eth_if)
927  memcpy (rmp->mac_address, eth_if->address, 6);
928  vl_api_send_msg (reg, (u8 *) rmp);
929 }
930 
933 {
934  vl_api_sw_interface_set_rx_mode_reply_t *rmp;
935  vnet_main_t *vnm = vnet_get_main ();
936  u32 sw_if_index = ntohl (mp->sw_if_index);
938  clib_error_t *error;
939  int rv = 0;
940 
942 
943  si = vnet_get_sw_interface (vnm, sw_if_index);
945  {
946  rv = VNET_API_ERROR_INVALID_VALUE;
947  goto bad_sw_if_index;
948  }
949 
951  mp->queue_id_valid,
952  ntohl (mp->queue_id), mp->mode);
953  if (error)
954  {
955  rv = VNET_API_ERROR_UNIMPLEMENTED;
956  clib_error_report (error);
957  goto out;
958  }
959 
961 out:
962  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
963 }
964 
965 static void
968  u32 sw_if_index, u32 worker_id,
969  u32 queue_id, u8 mode, u32 context)
970 {
972  mp = vl_msg_api_alloc (sizeof (*mp));
973  clib_memset (mp, 0, sizeof (*mp));
974 
975  mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_RX_PLACEMENT_DETAILS);
976  mp->sw_if_index = htonl (sw_if_index);
977  mp->queue_id = htonl (queue_id);
978  mp->worker_id = htonl (worker_id);
979  mp->mode = mode;
980  mp->context = context;
981 
982  vl_api_send_msg (rp, (u8 *) mp);
983 }
984 
987 {
988  vnet_main_t *vnm = vnet_get_main ();
990  u32 sw_if_index = ntohl (mp->sw_if_index);
992 
994  if (!reg)
995  return;
996 
997  if (sw_if_index == ~0)
998  {
1002  (u8 *) "device-input");
1003  uword si;
1004  int index = 0;
1005 
1006  /* *INDENT-OFF* */
1007  foreach_vlib_main (({
1009  ({
1010  rt = vlib_node_get_runtime_data (this_vlib_main, si);
1011  vec_foreach (dq, rt->devices_and_queues)
1012  {
1013  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm,
1014  dq->hw_if_index);
1015  send_interface_rx_placement_details (am, reg, hw->sw_if_index, index,
1016  dq->queue_id, dq->mode, mp->context);
1017  }
1018  }));
1019  index++;
1020  }));
1021  /* *INDENT-ON* */
1022  }
1023  else
1024  {
1025  int i;
1026  vnet_sw_interface_t *si;
1027 
1028  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
1029  {
1030  clib_warning ("sw_if_index %u does not exist", sw_if_index);
1031  goto bad_sw_if_index;
1032  }
1033 
1034  si = vnet_get_sw_interface (vnm, sw_if_index);
1036  {
1037  clib_warning ("interface type is not HARDWARE! P2P, PIPE and SUB"
1038  " interfaces are not supported");
1039  goto bad_sw_if_index;
1040  }
1041 
1043 
1044  for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++)
1045  {
1048  [i], i,
1049  hw->rx_mode_by_queue[i],
1050  mp->context);
1051  }
1052  }
1053 
1055 }
1056 
1059 {
1060  vl_api_sw_interface_set_rx_placement_reply_t *rmp;
1061  vnet_main_t *vnm = vnet_get_main ();
1062  u32 sw_if_index = ntohl (mp->sw_if_index);
1063  vnet_sw_interface_t *si;
1064  clib_error_t *error = 0;
1065  int rv = 0;
1066 
1067  VALIDATE_SW_IF_INDEX (mp);
1068 
1069  si = vnet_get_sw_interface (vnm, sw_if_index);
1071  {
1072  rv = VNET_API_ERROR_INVALID_VALUE;
1073  goto bad_sw_if_index;
1074  }
1075 
1077  ntohl (mp->queue_id),
1078  ntohl (mp->worker_id), mp->is_main);
1079  if (error)
1080  {
1081  rv = VNET_API_ERROR_UNIMPLEMENTED;
1082  clib_error_report (error);
1083  goto out;
1084  }
1085 
1087 out:
1088  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_PLACEMENT_REPLY);
1089 }
1090 
1091 static void
1093 {
1095  vnet_main_t *vnm = vnet_get_main ();
1096  u32 sw_if_index = (u32) ~ 0;
1098  int rv = 0;
1099  u32 id;
1100  vnet_sw_interface_t template;
1101  uword *p;
1103  u64 sup_and_sub_key;
1104  vl_api_registration_t *reg;
1105  clib_error_t *error;
1106 
1107  VALIDATE_SW_IF_INDEX (mp);
1108 
1109  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1110 
1112  {
1113  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1114  goto out;
1115  }
1116 
1117  id = ntohl (mp->vlan_id);
1118  if (id == 0 || id > 4095)
1119  {
1120  rv = VNET_API_ERROR_INVALID_VLAN;
1121  goto out;
1122  }
1123 
1124  sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1125 
1126  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1127  if (p)
1128  {
1129  rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1130  goto out;
1131  }
1132 
1133  clib_memset (&template, 0, sizeof (template));
1134  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1135  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1136  template.sup_sw_if_index = hi->sw_if_index;
1137  template.sub.id = id;
1138  template.sub.eth.raw_flags = 0;
1139  template.sub.eth.flags.one_tag = 1;
1140  template.sub.eth.outer_vlan_id = id;
1141  template.sub.eth.flags.exact_match = 1;
1142 
1143  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1144  if (error)
1145  {
1146  clib_error_report (error);
1147  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1148  goto out;
1149  }
1150 
1151  u64 *kp = clib_mem_alloc (sizeof (*kp));
1152  *kp = sup_and_sub_key;
1153 
1154  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1155  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1156 
1158 
1159 out:
1161  if (!reg)
1162  return;
1163 
1164  rmp = vl_msg_api_alloc (sizeof (*rmp));
1165  rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
1166  rmp->context = mp->context;
1167  rmp->retval = htonl (rv);
1168  rmp->sw_if_index = htonl (sw_if_index);
1169  vl_api_send_msg (reg, (u8 *) rmp);
1170 }
1171 
1172 static void
1174 {
1176  vnet_main_t *vnm = vnet_get_main ();
1177  u32 sw_if_index = ~0;
1178  int rv = 0;
1179  u32 sub_id;
1180  vnet_sw_interface_t *si;
1182  vnet_sw_interface_t template;
1183  uword *p;
1185  u64 sup_and_sub_key;
1186  clib_error_t *error;
1187 
1188  VALIDATE_SW_IF_INDEX (mp);
1189 
1190  si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1191  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1192 
1194  {
1195  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1196  goto out;
1197  }
1198 
1199  sw_if_index = si->sw_if_index;
1200  sub_id = ntohl (mp->sub_id);
1201 
1202  sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1203 
1204  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1205  if (p)
1206  {
1207  if (CLIB_DEBUG > 0)
1208  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1209  sw_if_index, sub_id);
1210  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1211  goto out;
1212  }
1213 
1214  clib_memset (&template, 0, sizeof (template));
1215  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1216  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1217  template.sup_sw_if_index = sw_if_index;
1218  template.sub.id = sub_id;
1219  template.sub.eth.flags.no_tags = mp->no_tags;
1220  template.sub.eth.flags.one_tag = mp->one_tag;
1221  template.sub.eth.flags.two_tags = mp->two_tags;
1222  template.sub.eth.flags.dot1ad = mp->dot1ad;
1223  template.sub.eth.flags.exact_match = mp->exact_match;
1224  template.sub.eth.flags.default_sub = mp->default_sub;
1225  template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1226  template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1227  template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1228  template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1229 
1230  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1231  if (error)
1232  {
1233  clib_error_report (error);
1234  rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1235  goto out;
1236  }
1237 
1238  u64 *kp = clib_mem_alloc (sizeof (*kp));
1239  *kp = sup_and_sub_key;
1240 
1241  hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1242  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1243 
1245 
1246 out:
1247 
1248  /* *INDENT-OFF* */
1249  REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1250  ({
1251  rmp->sw_if_index = ntohl(sw_if_index);
1252  }));
1253  /* *INDENT-ON* */
1254 }
1255 
1256 static void
1258 {
1259  vl_api_delete_subif_reply_t *rmp;
1260  int rv;
1261 
1262  rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
1263 
1264  REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
1265 }
1266 
1267 static void
1269  mp)
1270 {
1271  vl_api_interface_name_renumber_reply_t *rmp;
1272  int rv = 0;
1273 
1274  VALIDATE_SW_IF_INDEX (mp);
1275 
1277  (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
1278 
1280 
1281  REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
1282 }
1283 
1284 static void
1286 {
1288  u32 sw_if_index;
1289  int rv;
1290 
1291  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address, 0, 0);
1292 
1293  /* *INDENT-OFF* */
1294  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
1295  ({
1296  rmp->sw_if_index = ntohl (sw_if_index);
1297  }));
1298  /* *INDENT-ON* */
1299 }
1300 
1303 {
1305  u32 sw_if_index;
1306  u8 is_specified = mp->is_specified;
1307  u32 user_instance = ntohl (mp->user_instance);
1308  int rv;
1309 
1310  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address,
1311  is_specified, user_instance);
1312 
1313  /* *INDENT-OFF* */
1314  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_INSTANCE_REPLY,
1315  ({
1316  rmp->sw_if_index = ntohl (sw_if_index);
1317  }));
1318  /* *INDENT-ON* */
1319 }
1320 
1321 static void
1323 {
1324  vl_api_delete_loopback_reply_t *rmp;
1325  u32 sw_if_index;
1326  int rv;
1327 
1328  sw_if_index = ntohl (mp->sw_if_index);
1329  rv = vnet_delete_loopback_interface (sw_if_index);
1330 
1331  REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
1332 }
1333 
1334 static void
1337 {
1338  vl_api_collect_detailed_interface_stats_reply_t *rmp;
1339  int rv = 0;
1340 
1341  rv =
1343  mp->enable_disable);
1344 
1345  REPLY_MACRO (VL_API_COLLECT_DETAILED_INTERFACE_STATS_REPLY);
1346 }
1347 
1348 /*
1349  * vpe_api_hookup
1350  * Add vpe's API message handlers to the table.
1351  * vlib has already mapped shared memory and
1352  * added the client registration handlers.
1353  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1354  */
1355 #define vl_msg_name_crc_list
1356 #include <vnet/interface.api.h>
1357 #undef vl_msg_name_crc_list
1358 
1359 static void
1361 {
1362 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1363  foreach_vl_msg_name_crc_interface;
1364 #undef _
1365 }
1366 
1367 pub_sub_handler (interface_events, INTERFACE_EVENTS);
1368 
1369 static clib_error_t *
1371 {
1372  api_main_t *am = &api_main;
1373 
1374 #define _(N,n) \
1375  vl_msg_api_set_handlers(VL_API_##N, #n, \
1376  vl_api_##n##_t_handler, \
1377  vl_noop_handler, \
1378  vl_api_##n##_t_endian, \
1379  vl_api_##n##_t_print, \
1380  sizeof(vl_api_##n##_t), 1);
1382 #undef _
1383 
1384  /* Mark these APIs as mp safe */
1385  am->is_mp_safe[VL_API_SW_INTERFACE_DUMP] = 1;
1386  am->is_mp_safe[VL_API_SW_INTERFACE_DETAILS] = 1;
1387  am->is_mp_safe[VL_API_SW_INTERFACE_TAG_ADD_DEL] = 1;
1388 
1389  /* Do not replay VL_API_SW_INTERFACE_DUMP messages */
1390  am->api_trace_cfg[VL_API_SW_INTERFACE_DUMP].replay_enable = 0;
1391 
1392  /*
1393  * Set up the (msg_name, crc, message-id) table
1394  */
1396 
1397  return 0;
1398 }
1399 
1401 
1402 /*
1403  * fd.io coding-style-patch-verification: ON
1404  *
1405  * Local Variables:
1406  * eval: (c-set-style "gnu")
1407  * End:
1408  */
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
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:611
#define hash_set(h, key, value)
Definition: hash.h:255
u32 flags
Definition: vhost_user.h:141
ip4_table_bind_function_t * function
Definition: ip4.h:92
vnet_main_t * vnet_main
#define CLIB_UNUSED(x)
Definition: clib.h:82
Enable or disable detailed interface stats.
Definition: interface.api:590
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:696
Get interface&#39;s MAC address.
Definition: interface.api:348
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:46
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)
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(link_up_down_function)
ethernet_main_t * ethernet_get_main(vlib_main_t *vm)
Definition: init.c:120
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)
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:967
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:398
u32 * input_node_thread_index_by_queue
Definition: interface.h:570
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
From the CLI.
Definition: fib_entry.h:83
static void vl_api_delete_loopback_t_handler(vl_api_delete_loopback_t *mp)
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1374
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)
vl_api_address_t src
Definition: gre.api:51
int i
VLIB_API_INIT_FUNCTION(interface_api_hookup)
#define hash_set_mem(h, key, value)
Definition: hash.h:275
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
ip_lookup_main_t lookup_main
Definition: ip4.h:107
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:553
vlib_main_t * vlib_main
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:121
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:577
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:250
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:493
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:124
Set an interface&#39;s rx-mode.
Definition: interface.api:377
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:61
Clear interface statistics.
Definition: interface.api:306
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
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:842
u8 dst_address[6]
Definition: packet.h:55
Reply for the vlan subinterface create request.
Definition: interface.api:501
vnet_hw_interface_flags_t flags
Definition: interface.h:505
static void vl_api_sw_interface_rx_placement_dump_t_handler(vl_api_sw_interface_rx_placement_dump_t *mp)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
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:266
u32 mtu[VNET_N_MTU]
Definition: interface.h:716
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:1075
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:675
u32 max_supported_packet_bytes
Definition: interface.h:544
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:637
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)
vnet_crypto_main_t * cm
Definition: quic_crypto.c:41
format_function_t format_vnet_sw_interface_name
#define VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT
Definition: interface.h:491
#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:719
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:702
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:84
unsigned short u16
Definition: types.h:57
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:836
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:278
#define REPLY_MACRO(t)
vnet_sw_interface_flags_t flags
Definition: interface.h:699
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)
vl_api_interface_index_t sw_if_index
Definition: interface.api:218
static void vl_api_create_loopback_t_handler(vl_api_create_loopback_t *mp)
Create loopback interface instance response.
Definition: interface.api:564
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:841
u32 vl_api_string_len(vl_api_string_t *astr)
Definition: api_shared.c:1084
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:731
void vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1494
void ip_del_all_interface_addresses(vlib_main_t *vm, u32 sw_if_index)
Definition: ip46_cli.c:82
#define foreach_vlib_main(body)
Definition: threads.h:236
Set or delete one or all ip addresses on a specified interface.
Definition: interface.api:233
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:1248
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:203
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:46
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:564
#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
show the interface&#39;s queue - thread placement This api is used to display the interface and queue wor...
Definition: interface.api:436
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)
#define clib_warning(format, args...)
Definition: error.h:59
Request all or filtered subset of sw_interface_details.
Definition: interface.api:214
static void vl_api_create_loopback_instance_t_handler(vl_api_create_loopback_instance_t *mp)
Delete sub interface request.
Definition: interface.api:513
#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:576
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:1268
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:360
ip6_main_t ip6_main
Definition: ip6_forward.c:2671
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:1134
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:79
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:153
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
Interface Event generated by want_interface_events.
Definition: interface.api:88
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:146
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:723
static void vl_api_create_subif_t_handler(vl_api_create_subif_t *mp)
Create loopback interface instance request.
Definition: interface.api:550
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:886
struct vnet_sub_interface_t::@210::@211::@213 flags
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:553
u64 uword
Definition: types.h:112
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:833
Create loopback interface request.
Definition: interface.api:524
ip6_table_bind_function_t * function
Definition: ip6.h:114
Set unnumbered interface add / del request.
Definition: interface.api:292
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
struct vnet_sub_interface_t::@210 eth
A collection of combined counters.
Definition: counter.h:188
Create a new subinterface with the given vlan id.
Definition: interface.api:488
int vnet_sw_interface_stats_collect_enable_disable(u32 sw_if_index, u8 enable)
Create loopback interface response.
Definition: interface.api:536
#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:414
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
u8 * vl_api_from_api_string(vl_api_string_t *astr)
Definition: api_shared.c:1078
Set an interface&#39;s MAC address.
Definition: interface.api:335
u8 * is_mp_safe
Message is mp safe vector.
Definition: api_common.h:226
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:44
vnet_sw_interface_type_t type
Definition: interface.h:697
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:921
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:510
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:1485
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:587
Interface details structure (fix this)
Definition: interface.api:141
static void vl_api_sw_interface_set_table_t_handler(vl_api_sw_interface_set_table_t *mp)
u32 table_id
Definition: fib_types.api:118
#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:320
ethernet_interface_t * interfaces
Definition: ethernet.h:272
Associate the specified interface with a fib table.
Definition: interface.api:252
static void vl_api_sw_interface_get_mac_address_t_handler(vl_api_sw_interface_get_mac_address_t *mp)
u32 context
Definition: gre.api:45
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
vl_api_interface_index_t sw_if_index
Definition: interface.api:325