FD.io VPP  v18.10-32-g1161dda
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  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;
207  mp->link_mtu = ntohs (hi->max_packet_bytes);
208  mp->mtu[VNET_MTU_L3] = ntohl (swif->mtu[VNET_MTU_L3]);
209  mp->mtu[VNET_MTU_IP4] = ntohl (swif->mtu[VNET_MTU_IP4]);
210  mp->mtu[VNET_MTU_IP6] = ntohl (swif->mtu[VNET_MTU_IP6]);
211  mp->mtu[VNET_MTU_MPLS] = ntohl (swif->mtu[VNET_MTU_MPLS]);
212 
213  mp->context = context;
214 
215  strncpy ((char *) mp->interface_name,
216  (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
217 
218  /* Send the L2 address for ethernet physical intfcs */
219  if (swif->sup_sw_if_index == swif->sw_if_index
221  {
224 
225  ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
226  ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
227  clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
228  mp->l2_address_length = ntohl (sizeof (ei->address));
229  }
230  else if (swif->sup_sw_if_index != swif->sw_if_index)
231  {
232  vnet_sub_interface_t *sub = &swif->sub;
233  mp->sub_id = ntohl (sub->id);
234  mp->sub_dot1ad = sub->eth.flags.dot1ad;
235  mp->sub_number_of_tags =
236  sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
237  mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
238  mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
239  mp->sub_exact_match = sub->eth.flags.exact_match;
240  mp->sub_default = sub->eth.flags.default_sub;
241  mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
242  mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
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 
265  /* pbb tag rewrite data */
266  ethernet_header_t eth_hdr;
267  u32 vtr_op = L2_VTR_DISABLED;
268  u16 outer_tag = 0;
269  u16 b_vlanid = 0;
270  u32 i_sid = 0;
271  memset (&eth_hdr, 0, sizeof (eth_hdr));
272 
273  if (!l2pbb_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
274  &vtr_op, &outer_tag, &eth_hdr, &b_vlanid, &i_sid))
275  {
276  mp->sub_dot1ah = 1;
277  clib_memcpy (mp->b_dmac, eth_hdr.dst_address,
278  sizeof (eth_hdr.dst_address));
279  clib_memcpy (mp->b_smac, eth_hdr.src_address,
280  sizeof (eth_hdr.src_address));
281  mp->b_vlanid = b_vlanid;
282  mp->i_sid = i_sid;
283  }
284 
286  if (tag)
287  strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
288 
289  vl_api_send_msg (rp, (u8 *) mp);
290 }
291 
292 static void
294 {
296  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  if (mp->name_filter_valid)
310  {
311  mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
312  filter = format (0, "%s%c", mp->name_filter, 0);
313  }
314 
315  char *strcasestr (char *, char *); /* lnx hdr file botch */
316  /* *INDENT-OFF* */
317  pool_foreach (swif, im->sw_interfaces,
318  ({
319  if (!vnet_swif_is_api_visible (swif))
320  continue;
321  vec_reset_length(name);
322  name = format (name, "%U%c", format_vnet_sw_interface_name, am->vnet_main,
323  swif, 0);
324 
325  if (filter && !strcasestr((char *) name, (char *) filter))
326  continue;
327 
328  send_sw_interface_details (am, rp, swif, name, mp->context);
329  }));
330  /* *INDENT-ON* */
331 
332  vec_free (name);
333  vec_free (filter);
334 }
335 
336 static void
339 {
340  vlib_main_t *vm = vlib_get_main ();
341  vnet_main_t *vnm = vnet_get_main ();
342  vl_api_sw_interface_add_del_address_reply_t *rmp;
343  int rv = 0;
344  u32 is_del;
345  clib_error_t *error = 0;
346 
348 
349  is_del = mp->is_add == 0;
350  vnm->api_errno = 0;
351 
352  if (mp->del_all)
354  else if (mp->is_ipv6)
355  error = ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
356  (void *) mp->address,
357  mp->address_length, is_del);
358  else
359  error = ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
360  (void *) mp->address,
361  mp->address_length, is_del);
362 
363  if (error)
364  {
365  rv = vnm->api_errno;
366  clib_error_report (error);
367  goto done;
368  }
369 
371 
372 done:
373  REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
374 }
375 
376 void stats_dslock_with_hint (int hint, int tag) __attribute__ ((weak));
377 void
378 stats_dslock_with_hint (int hint, int tag)
379 {
380 }
381 
382 void stats_dsunlock (void) __attribute__ ((weak));
383 void
385 {
386 }
387 
388 static void
390 {
391  vl_api_sw_interface_set_table_reply_t *rmp;
392  u32 sw_if_index = ntohl (mp->sw_if_index);
393  u32 table_id = ntohl (mp->vrf_id);
394  int rv = 0;
395 
397 
398  stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ );
399 
400  if (mp->is_ipv6)
401  rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, table_id, 1);
402  else
403  rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, table_id, 1);
404 
405  stats_dsunlock ();
406 
408 
409  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
410 }
411 
412 int
414  u32 sw_if_index, u32 table_id, u8 is_api)
415 {
417  u32 fib_index, mfib_index;
419  mfib_source_t msrc;
420 
421  if (is_api)
422  {
423  src = FIB_SOURCE_API;
424  msrc = MFIB_SOURCE_API;
425  }
426  else
427  {
428  src = FIB_SOURCE_CLI;
429  msrc = MFIB_SOURCE_CLI;
430  }
431 
432  /*
433  * This if table does not exist = error is what we want in the end.
434  */
435  fib_index = fib_table_find (fproto, table_id);
436  mfib_index = mfib_table_find (fproto, table_id);
437 
438  if (~0 == fib_index || ~0 == mfib_index)
439  {
440  return (VNET_API_ERROR_NO_SUCH_FIB);
441  }
442 
443  if (FIB_PROTOCOL_IP6 == fproto)
444  {
445  /*
446  * If the interface already has in IP address, then a change int
447  * VRF is not allowed. The IP address applied must first be removed.
448  * We do not do that automatically here, since VPP has no knowledge
449  * of whether those subnets are valid in the destination VRF.
450  */
451  /* *INDENT-OFF* */
453  ia, sw_if_index,
454  1 /* honor unnumbered */ ,
455  ({
456  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
457  }));
458  /* *INDENT-ON* */
459 
462 
463  /*
464  * tell those that are interested that the binding is changing.
465  */
468  cb->function (&ip6_main, cb->function_opaque,
469  sw_if_index,
470  fib_index,
471  ip6_main.fib_index_by_sw_if_index[sw_if_index]);
472 
473  if (0 == table_id)
474  {
475  /* reset back to default */
476  if (0 != ip6_main.fib_index_by_sw_if_index[sw_if_index])
478  FIB_PROTOCOL_IP6, src);
479  if (0 != ip6_main.mfib_index_by_sw_if_index[sw_if_index])
481  [sw_if_index], FIB_PROTOCOL_IP6, msrc);
482 
483  }
484  else
485  {
486  /* we need to lock the table now it's inuse */
487  fib_table_lock (fib_index, FIB_PROTOCOL_IP6, src);
488  mfib_table_lock (mfib_index, FIB_PROTOCOL_IP6, msrc);
489  }
490 
493  }
494  else
495  {
496  /*
497  * If the interface already has in IP address, then a change int
498  * VRF is not allowed. The IP address applied must first be removed.
499  * We do not do that automatically here, since VPP has no knowledge
500  * of whether those subnets are valid in the destination VRF.
501  */
502  /* *INDENT-OFF* */
504  ia, sw_if_index,
505  1 /* honor unnumbered */ ,
506  ({
507  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
508  }));
509  /* *INDENT-ON* */
510 
513 
514  /*
515  * tell those that are interested that the binding is changing.
516  */
519  cb->function (&ip4_main, cb->function_opaque,
520  sw_if_index,
521  fib_index,
522  ip4_main.fib_index_by_sw_if_index[sw_if_index]);
523 
524  if (0 == table_id)
525  {
526  /* reset back to default */
527  if (0 != ip4_main.fib_index_by_sw_if_index[sw_if_index])
529  FIB_PROTOCOL_IP4, src);
530  if (0 != ip4_main.mfib_index_by_sw_if_index[sw_if_index])
532  [sw_if_index], FIB_PROTOCOL_IP4, msrc);
533 
534  }
535  else
536  {
537  /* we need to lock the table now it's inuse */
539  table_id, src);
540 
542  table_id, msrc);
543  }
544 
547  }
548 
549  return (0);
550 }
551 
552 static void
554  u32 context, int retval, u32 vrf_id)
555 {
557 
558  mp = vl_msg_api_alloc (sizeof (*mp));
559  memset (mp, 0, sizeof (*mp));
560  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_GET_TABLE_REPLY);
561  mp->context = context;
562  mp->retval = htonl (retval);
563  mp->vrf_id = htonl (vrf_id);
564 
565  vl_api_send_msg (reg, (u8 *) mp);
566 }
567 
568 static void
570 {
572  fib_table_t *fib_table = 0;
573  u32 sw_if_index = ~0;
574  u32 fib_index = ~0;
575  u32 table_id = ~0;
576  fib_protocol_t fib_proto = FIB_PROTOCOL_IP4;
577  int rv = 0;
578 
580  if (!reg)
581  return;
582 
584 
585  sw_if_index = ntohl (mp->sw_if_index);
586 
587  if (mp->is_ipv6)
588  fib_proto = FIB_PROTOCOL_IP6;
589 
590  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
591  if (fib_index != ~0)
592  {
593  fib_table = fib_table_get (fib_index, fib_proto);
594  table_id = fib_table->ft_table_id;
595  }
596 
598 
599  send_sw_interface_get_table_reply (reg, mp->context, rv, table_id);
600 }
601 
604 {
605  vl_api_sw_interface_set_unnumbered_reply_t *rmp;
606  int rv = 0;
607  vnet_main_t *vnm = vnet_get_main ();
608  u32 sw_if_index = ntohl (mp->sw_if_index);
609  u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
610 
611  /*
612  * The API message field names are backwards from
613  * the underlying data structure names.
614  * It's not worth changing them now.
615  */
616  if (!vnet_sw_interface_is_api_valid (vnm, unnumbered_sw_if_index))
617  {
618  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
619  goto done;
620  }
621 
622  /* Only check the "use loop0" field when setting the binding */
623  if (mp->is_add && !vnet_sw_interface_is_api_valid (vnm, sw_if_index))
624  {
625  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
626  goto done;
627  }
628 
629  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
630  sw_if_index, mp->is_add);
631 done:
632  REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
633 }
634 
635 static void
637  mp)
638 {
639  vl_api_sw_interface_clear_stats_reply_t *rmp;
640 
641  vnet_main_t *vnm = vnet_get_main ();
645  static vnet_main_t **my_vnet_mains;
646  int i, j, n_counters;
647  int rv = 0;
648 
649  if (mp->sw_if_index != ~0)
651 
652  vec_reset_length (my_vnet_mains);
653 
654  for (i = 0; i < vec_len (vnet_mains); i++)
655  {
656  if (vnet_mains[i])
657  vec_add1 (my_vnet_mains, vnet_mains[i]);
658  }
659 
660  if (vec_len (vnet_mains) == 0)
661  vec_add1 (my_vnet_mains, vnm);
662 
663  n_counters = vec_len (im->combined_sw_if_counters);
664 
665  for (j = 0; j < n_counters; j++)
666  {
667  for (i = 0; i < vec_len (my_vnet_mains); i++)
668  {
669  im = &my_vnet_mains[i]->interface_main;
670  cm = im->combined_sw_if_counters + j;
671  if (mp->sw_if_index == (u32) ~ 0)
673  else
674  vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
675  }
676  }
677 
678  n_counters = vec_len (im->sw_if_counters);
679 
680  for (j = 0; j < n_counters; j++)
681  {
682  for (i = 0; i < vec_len (my_vnet_mains); i++)
683  {
684  im = &my_vnet_mains[i]->interface_main;
685  sm = im->sw_if_counters + j;
686  if (mp->sw_if_index == (u32) ~ 0)
688  else
689  vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
690  }
691  }
692 
694 
695  REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
696 }
697 
698 #define API_LINK_STATE_EVENT 1
699 #define API_ADMIN_UP_DOWN_EVENT 2
700 
701 static int
702 event_data_cmp (void *a1, void *a2)
703 {
704  uword *e1 = a1;
705  uword *e2 = a2;
706 
707  return (word) e1[0] - (word) e2[0];
708 }
709 
710 static void
713  vl_api_registration_t * vl_reg,
714  vnet_sw_interface_t * swif)
715 {
717  vnet_main_t *vnm = am->vnet_main;
718 
720  swif->sw_if_index);
721  mp = vl_msg_api_alloc (sizeof (*mp));
722  memset (mp, 0, sizeof (*mp));
723  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_EVENT);
724  mp->sw_if_index = ntohl (swif->sw_if_index);
725  mp->client_index = reg->client_index;
726  mp->pid = reg->client_pid;
727 
728  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
729  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
730  vl_api_send_msg (vl_reg, (u8 *) mp);
731 }
732 
733 static uword
736 {
738  vnet_main_t *vnm = vam->vnet_main;
739  vnet_sw_interface_t *swif;
740  uword *event_data = 0;
742  int i;
743  u32 prev_sw_if_index;
744  vl_api_registration_t *vl_reg;
745 
746  vam->link_state_process_up = 1;
747 
748  while (1)
749  {
751 
752  /* Unified list of changed link or admin state sw_if_indices */
754  (vm, &event_data, API_LINK_STATE_EVENT);
756  (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
757 
758  /* Sort, so we can eliminate duplicates */
760 
761  prev_sw_if_index = ~0;
762 
763  for (i = 0; i < vec_len (event_data); i++)
764  {
765  /* Only one message per swif */
766  if (prev_sw_if_index == event_data[i])
767  continue;
768  prev_sw_if_index = event_data[i];
769 
770  /* *INDENT-OFF* */
771  pool_foreach(reg, vam->interface_events_registrations,
772  ({
773  vl_reg = vl_api_client_index_to_registration (reg->client_index);
774  if (vl_reg)
775  {
776  /* sw_interface may be deleted already */
777  if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
778  event_data[i]))
779  {
780  swif = vnet_get_sw_interface (vnm, event_data[i]);
781  send_sw_interface_event (vam, reg, vl_reg, swif);
782  }
783  }
784  }));
785  /* *INDENT-ON* */
786  }
787  vec_reset_length (event_data);
788  }
789 
790  return 0;
791 }
792 
793 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
794  u32 flags);
796  u32 hw_if_index, u32 flags);
797 
798 /* *INDENT-OFF* */
799 VLIB_REGISTER_NODE (link_state_process_node,static) = {
800  .function = link_state_process,
801  .type = VLIB_NODE_TYPE_PROCESS,
802  .name = "vpe-link-state-process",
803 };
804 /* *INDENT-ON* */
805 
806 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
807 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
808 
809 static clib_error_t *
810 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
811 {
813  vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
814 
815  if (vam->link_state_process_up)
817  link_state_process_node.index,
819  return 0;
820 }
821 
822 static clib_error_t *
824 {
826 
827  /*
828  * Note: it's perfectly fair to set a subif admin up / admin down.
829  * Note the subtle distinction between this routine and the previous
830  * routine.
831  */
832  if (vam->link_state_process_up)
834  link_state_process_node.index,
835  API_ADMIN_UP_DOWN_EVENT, sw_if_index);
836  return 0;
837 }
838 
841 {
842  vnet_main_t *vnm = vnet_get_main ();
843  vl_api_sw_interface_tag_add_del_reply_t *rmp;
844  int rv = 0;
845  u8 *tag;
846  u32 sw_if_index = ntohl (mp->sw_if_index);
847 
849 
850  if (mp->is_add)
851  {
852  if (mp->tag[0] == 0)
853  {
854  rv = VNET_API_ERROR_INVALID_VALUE;
855  goto out;
856  }
857 
858  mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
859  tag = format (0, "%s%c", mp->tag, 0);
860  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
861  }
862  else
863  vnet_clear_sw_interface_tag (vnm, sw_if_index);
864 
866 out:
867  REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY);
868 }
869 
872 {
873  vl_api_sw_interface_set_mac_address_reply_t *rmp;
874  vnet_main_t *vnm = vnet_get_main ();
875  u32 sw_if_index = ntohl (mp->sw_if_index);
877  clib_error_t *error;
878  int rv = 0;
879 
881 
882  si = vnet_get_sw_interface (vnm, sw_if_index);
884  mp->mac_address);
885  if (error)
886  {
887  rv = VNET_API_ERROR_UNIMPLEMENTED;
888  clib_error_report (error);
889  goto out;
890  }
891 
893 out:
894  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
895 }
896 
899 {
902  vnet_main_t *vnm = vnet_get_main ();
903  u32 sw_if_index = ntohl (mp->sw_if_index);
905  ethernet_interface_t *eth_if = 0;
906  int rv = 0;
907 
909 
910  si = vnet_get_sup_sw_interface (vnm, sw_if_index);
913 
915 
917  if (!reg)
918  return;
919  rmp = vl_msg_api_alloc (sizeof (*rmp));
920  rmp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS_REPLY);
921  rmp->context = mp->context;
922  rmp->retval = htonl (rv);
923  if (!rv && eth_if)
924  memcpy (rmp->mac_address, eth_if->address, 6);
925  vl_api_send_msg (reg, (u8 *) rmp);
926 }
927 
930 {
931  vl_api_sw_interface_set_rx_mode_reply_t *rmp;
932  vnet_main_t *vnm = vnet_get_main ();
933  u32 sw_if_index = ntohl (mp->sw_if_index);
935  clib_error_t *error;
936  int rv = 0;
937 
939 
940  si = vnet_get_sw_interface (vnm, sw_if_index);
942  {
943  rv = VNET_API_ERROR_INVALID_VALUE;
944  goto bad_sw_if_index;
945  }
946 
948  mp->queue_id_valid,
949  ntohl (mp->queue_id), mp->mode);
950  if (error)
951  {
952  rv = VNET_API_ERROR_UNIMPLEMENTED;
953  clib_error_report (error);
954  goto out;
955  }
956 
958 out:
959  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
960 }
961 
962 static void
965  u32 sw_if_index, u32 worker_id,
966  u32 queue_id, u8 mode, u32 context)
967 {
969  mp = vl_msg_api_alloc (sizeof (*mp));
970  memset (mp, 0, sizeof (*mp));
971 
972  mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_RX_PLACEMENT_DETAILS);
973  mp->sw_if_index = htonl (sw_if_index);
974  mp->queue_id = htonl (queue_id);
975  mp->worker_id = htonl (worker_id);
976  mp->mode = mode;
977  mp->context = context;
978 
979  vl_api_send_msg (rp, (u8 *) mp);
980 }
981 
984 {
985  vnet_main_t *vnm = vnet_get_main ();
987  u32 sw_if_index = ntohl (mp->sw_if_index);
989 
991  if (!reg)
992  return;
993 
994  if (sw_if_index == ~0)
995  {
999  (u8 *) "device-input");
1000  uword si;
1001  int index = 0;
1002 
1003  /* *INDENT-OFF* */
1004  foreach_vlib_main (({
1006  ({
1007  rt = vlib_node_get_runtime_data (this_vlib_main, si);
1008  vec_foreach (dq, rt->devices_and_queues)
1009  {
1010  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm,
1011  dq->hw_if_index);
1012  send_interface_rx_placement_details (am, reg, hw->sw_if_index, index,
1013  dq->queue_id, dq->mode, mp->context);
1014  }
1015  }));
1016  index++;
1017  }));
1018  /* *INDENT-ON* */
1019  }
1020  else
1021  {
1022  int i;
1023  vnet_sw_interface_t *si;
1024 
1026  {
1027  clib_warning ("sw_if_index %u does not exist", sw_if_index);
1028  goto bad_sw_if_index;
1029  }
1030 
1031  si = vnet_get_sw_interface (vnm, sw_if_index);
1033  {
1034  clib_warning ("interface type is not HARDWARE! P2P, PIPE and SUB"
1035  " interfaces are not supported");
1036  goto bad_sw_if_index;
1037  }
1038 
1040 
1041  for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++)
1042  {
1045  [i], i,
1046  hw->rx_mode_by_queue[i],
1047  mp->context);
1048  }
1049  }
1050 
1052 }
1053 
1056 {
1057  vl_api_sw_interface_set_rx_placement_reply_t *rmp;
1058  vnet_main_t *vnm = vnet_get_main ();
1059  u32 sw_if_index = ntohl (mp->sw_if_index);
1060  vnet_sw_interface_t *si;
1061  clib_error_t *error = 0;
1062  int rv = 0;
1063 
1064  VALIDATE_SW_IF_INDEX (mp);
1065 
1066  si = vnet_get_sw_interface (vnm, sw_if_index);
1068  {
1069  rv = VNET_API_ERROR_INVALID_VALUE;
1070  goto bad_sw_if_index;
1071  }
1072 
1074  ntohl (mp->queue_id),
1075  ntohl (mp->worker_id), mp->is_main);
1076  if (error)
1077  {
1078  rv = VNET_API_ERROR_UNIMPLEMENTED;
1079  clib_error_report (error);
1080  goto out;
1081  }
1082 
1084 out:
1085  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_PLACEMENT_REPLY);
1086 }
1087 
1088 static void
1090 {
1092  vnet_main_t *vnm = vnet_get_main ();
1093  u32 sw_if_index = (u32) ~ 0;
1095  int rv = 0;
1096  u32 id;
1097  vnet_sw_interface_t template;
1098  uword *p;
1100  u64 sup_and_sub_key;
1101  vl_api_registration_t *reg;
1102  clib_error_t *error;
1103 
1104  VALIDATE_SW_IF_INDEX (mp);
1105 
1106  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1107 
1109  {
1110  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1111  goto out;
1112  }
1113 
1114  id = ntohl (mp->vlan_id);
1115  if (id == 0 || id > 4095)
1116  {
1117  rv = VNET_API_ERROR_INVALID_VLAN;
1118  goto out;
1119  }
1120 
1121  sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1122 
1123  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1124  if (p)
1125  {
1126  rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1127  goto out;
1128  }
1129 
1130  memset (&template, 0, sizeof (template));
1131  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1132  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1133  template.sup_sw_if_index = hi->sw_if_index;
1134  template.sub.id = id;
1135  template.sub.eth.raw_flags = 0;
1136  template.sub.eth.flags.one_tag = 1;
1137  template.sub.eth.outer_vlan_id = id;
1138  template.sub.eth.flags.exact_match = 1;
1139 
1140  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1141  if (error)
1142  {
1143  clib_error_report (error);
1144  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1145  goto out;
1146  }
1147 
1148  u64 *kp = clib_mem_alloc (sizeof (*kp));
1149  *kp = sup_and_sub_key;
1150 
1151  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1152  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1153 
1155 
1156 out:
1158  if (!reg)
1159  return;
1160 
1161  rmp = vl_msg_api_alloc (sizeof (*rmp));
1162  rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
1163  rmp->context = mp->context;
1164  rmp->retval = htonl (rv);
1165  rmp->sw_if_index = htonl (sw_if_index);
1166  vl_api_send_msg (reg, (u8 *) rmp);
1167 }
1168 
1169 static void
1171 {
1173  vnet_main_t *vnm = vnet_get_main ();
1174  u32 sw_if_index = ~0;
1175  int rv = 0;
1176  u32 sub_id;
1177  vnet_sw_interface_t *si;
1179  vnet_sw_interface_t template;
1180  uword *p;
1182  u64 sup_and_sub_key;
1183  clib_error_t *error;
1184 
1185  VALIDATE_SW_IF_INDEX (mp);
1186 
1187  si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1188  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1189 
1191  {
1192  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1193  goto out;
1194  }
1195 
1196  sw_if_index = si->sw_if_index;
1197  sub_id = ntohl (mp->sub_id);
1198 
1199  sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1200 
1201  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1202  if (p)
1203  {
1204  if (CLIB_DEBUG > 0)
1205  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1206  sw_if_index, sub_id);
1207  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1208  goto out;
1209  }
1210 
1211  memset (&template, 0, sizeof (template));
1212  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1213  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
1214  template.sup_sw_if_index = sw_if_index;
1215  template.sub.id = sub_id;
1216  template.sub.eth.flags.no_tags = mp->no_tags;
1217  template.sub.eth.flags.one_tag = mp->one_tag;
1218  template.sub.eth.flags.two_tags = mp->two_tags;
1219  template.sub.eth.flags.dot1ad = mp->dot1ad;
1220  template.sub.eth.flags.exact_match = mp->exact_match;
1221  template.sub.eth.flags.default_sub = mp->default_sub;
1222  template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1223  template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1224  template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1225  template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1226 
1227  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1228  if (error)
1229  {
1230  clib_error_report (error);
1231  rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1232  goto out;
1233  }
1234 
1235  u64 *kp = clib_mem_alloc (sizeof (*kp));
1236  *kp = sup_and_sub_key;
1237 
1238  hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1239  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1240 
1242 
1243 out:
1244 
1245  /* *INDENT-OFF* */
1246  REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1247  ({
1248  rmp->sw_if_index = ntohl(sw_if_index);
1249  }));
1250  /* *INDENT-ON* */
1251 }
1252 
1253 static void
1255 {
1256  vl_api_delete_subif_reply_t *rmp;
1257  int rv;
1258 
1259  rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
1260 
1261  REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
1262 }
1263 
1264 static void
1266  mp)
1267 {
1268  vl_api_interface_name_renumber_reply_t *rmp;
1269  int rv = 0;
1270 
1271  VALIDATE_SW_IF_INDEX (mp);
1272 
1274  (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
1275 
1277 
1278  REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
1279 }
1280 
1281 static void
1283 {
1285  u32 sw_if_index;
1286  int rv;
1287 
1288  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address, 0, 0);
1289 
1290  /* *INDENT-OFF* */
1291  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
1292  ({
1293  rmp->sw_if_index = ntohl (sw_if_index);
1294  }));
1295  /* *INDENT-ON* */
1296 }
1297 
1300 {
1302  u32 sw_if_index;
1303  u8 is_specified = mp->is_specified;
1304  u32 user_instance = ntohl (mp->user_instance);
1305  int rv;
1306 
1307  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address,
1308  is_specified, user_instance);
1309 
1310  /* *INDENT-OFF* */
1311  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_INSTANCE_REPLY,
1312  ({
1313  rmp->sw_if_index = ntohl (sw_if_index);
1314  }));
1315  /* *INDENT-ON* */
1316 }
1317 
1318 static void
1320 {
1321  vl_api_delete_loopback_reply_t *rmp;
1322  u32 sw_if_index;
1323  int rv;
1324 
1325  sw_if_index = ntohl (mp->sw_if_index);
1326  rv = vnet_delete_loopback_interface (sw_if_index);
1327 
1328  REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
1329 }
1330 
1331 static void
1334 {
1335  vl_api_collect_detailed_interface_stats_reply_t *rmp;
1336  int rv = 0;
1337 
1338  rv =
1340  mp->enable_disable);
1341 
1342  REPLY_MACRO (VL_API_COLLECT_DETAILED_INTERFACE_STATS_REPLY);
1343 }
1344 
1345 /*
1346  * vpe_api_hookup
1347  * Add vpe's API message handlers to the table.
1348  * vlib has already mapped shared memory and
1349  * added the client registration handlers.
1350  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1351  */
1352 #define vl_msg_name_crc_list
1353 #include <vnet/interface.api.h>
1354 #undef vl_msg_name_crc_list
1355 
1356 static void
1358 {
1359 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1360  foreach_vl_msg_name_crc_interface;
1361 #undef _
1362 }
1363 
1364 pub_sub_handler (interface_events, INTERFACE_EVENTS);
1365 
1366 static clib_error_t *
1368 {
1369  api_main_t *am = &api_main;
1370 
1371 #define _(N,n) \
1372  vl_msg_api_set_handlers(VL_API_##N, #n, \
1373  vl_api_##n##_t_handler, \
1374  vl_noop_handler, \
1375  vl_api_##n##_t_endian, \
1376  vl_api_##n##_t_print, \
1377  sizeof(vl_api_##n##_t), 1);
1379 #undef _
1380 
1381  /*
1382  * Set up the (msg_name, crc, message-id) table
1383  */
1385 
1386  return 0;
1387 }
1388 
1390 
1391 /*
1392  * fd.io coding-style-patch-verification: ON
1393  *
1394  * Local Variables:
1395  * eval: (c-set-style "gnu")
1396  * End:
1397  */
static void vl_api_delete_subif_t_handler(vl_api_delete_subif_t *mp)
uword * sibling_bitmap
Definition: node.h:345
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:180
static int event_data_cmp(void *a1, void *a2)
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:467
#define hash_set(h, key, value)
Definition: hash.h:255
vl_api_address_t src
Definition: vxlan_gbp.api:33
ip4_table_bind_function_t * function
Definition: ip4.h:83
vnet_main_t * vnet_main
#define CLIB_UNUSED(x)
Definition: clib.h:81
Enable or disable detailed interface stats.
Definition: interface.api:638
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:638
Get interface&#39;s MAC address.
Definition: interface.api:396
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:619
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip6.h:179
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:116
Set flags on the interface.
Definition: interface.api:15
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: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:446
u32 * input_node_thread_index_by_queue
Definition: interface.h:596
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:523
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1311
static void vnet_clear_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
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:579
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:54
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
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)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:494
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
uword * dq_runtime_index_by_queue
Definition: interface.h:603
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
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:499
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)
int ip_table_bind(fib_protocol_t fproto, u32 sw_if_index, u32 table_id, u8 is_api)
struct vnet_sub_interface_t::@198::@199::@201 flags
#define VNET_HW_INTERFACE_FLAG_SPEED_MASK
Definition: interface.h:517
enum mfib_source_t_ mfib_source_t
Possible [control plane] sources of MFIB entries.
ethernet_main_t ethernet_main
Definition: init.c:45
memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:425
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:354
i64 word
Definition: types.h:111
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
u32 sw_if_index
Definition: vxlan_gbp.api:39
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:855
u8 dst_address[6]
Definition: packet.h:55
Reply for the vlan subinterface create request.
Definition: interface.api:549
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:240
u32 mtu[VNET_N_MTU]
Definition: interface.h:739
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:617
u32 max_supported_packet_bytes
Definition: interface.h:570
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:659
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:496
#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:464
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:269
vnet_sub_interface_t sub
Definition: interface.h:742
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:960
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:558
static void send_sw_interface_get_table_reply(vl_api_registration_t *reg, u32 context, int retval, u32 vrf_id)
#define VNET_HW_INTERFACE_FLAG_SPEED_SHIFT
Definition: interface.h:504
Set interface L3 MTU.
Definition: interface.api:39
unsigned short u16
Definition: types.h:57
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:849
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:200
Reply to get_sw_interface_vrf.
Definition: interface.api:252
#define REPLY_MACRO(t)
vnet_sw_interface_flags_t flags
Definition: interface.h:720
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:612
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:854
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:587
void vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1431
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:234
Set or delete one or all ip addresses on a specified interface.
Definition: interface.api:207
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:1236
u8 name[64]
Definition: memclnt.api:151
vnet_hw_interface_class_t ethernet_hw_interface_class
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
u32 flags
Definition: vhost_user.h:115
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:736
static uword vlib_process_get_events_with_type(vlib_main_t *vm, uword **data_vector, uword with_type_opaque)
Definition: node_funcs.h:597
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:590
#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:155
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
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:484
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:917
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
int vnet_delete_loopback_interface(u32 sw_if_index)
Definition: interface.c:897
static clib_error_t * admin_up_down_function(vnet_main_t *vm, u32 hw_if_index, u32 flags)
#define API_ADMIN_UP_DOWN_EVENT
struct vnet_sub_interface_t::@198 eth
#define clib_warning(format, args...)
Definition: error.h:59
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, u8 *mac_address)
Definition: interface.c:1422
#define clib_memcpy(a, b, c)
Definition: string.h:75
static void vl_api_create_loopback_instance_t_handler(vl_api_create_loopback_instance_t *mp)
Delete sub interface request.
Definition: interface.api:561
#define ARRAY_LEN(x)
Definition: clib.h:61
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:624
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:1265
foreach_registration_hash u8 link_state_process_up
static void send_sw_interface_event(vpe_api_main_t *am, vpe_client_registration_t *reg, vl_api_registration_t *vl_reg, vnet_sw_interface_t *swif)
#define ASSERT(truth)
Reply for get interface&#39;s MAC address request.
Definition: interface.api:408
ip6_main_t ip6_main
Definition: ip6_forward.c:2590
ip_lookup_main_t lookup_main
Definition: ip6.h:161
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 API_LINK_STATE_EVENT
#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:123
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:71
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:665
static void vl_api_create_subif_t_handler(vl_api_create_subif_t *mp)
Create loopback interface instance request.
Definition: interface.api:598
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:887
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Set interface physical MTU.
Definition: interface.api:30
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:409
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:982
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:846
Create loopback interface request.
Definition: interface.api:572
ip6_table_bind_function_t * function
Definition: ip6.h:115
Set unnumbered interface add / del request.
Definition: interface.api:340
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:172
Create a new subinterface with the given vlan id.
Definition: interface.api:536
int vnet_sw_interface_stats_collect_enable_disable(u32 sw_if_index, u8 enable)
Create loopback interface response.
Definition: interface.api:584
#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:462
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:383
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:718
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:900
pub_sub_handler(interface_events, INTERFACE_EVENTS)
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:477
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:193
u32 id
Definition: udp.api:45
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:529
Interface details structure (fix this)
Definition: interface.api:124
static void vl_api_sw_interface_set_table_t_handler(vl_api_sw_interface_set_table_t *mp)
Set / clear software interface tag.
Definition: interface.api:368
ethernet_interface_t * interfaces
Definition: ethernet.h:290
Associate the specified interface with a fib table.
Definition: interface.api:226
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:176
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