FD.io VPP  v18.07-rc0-415-g6c78436
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_SET_TABLE, sw_interface_set_table) \
60 _(SW_INTERFACE_GET_TABLE, sw_interface_get_table) \
61 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
62 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
63 _(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) \
64 _(SW_INTERFACE_SET_MAC_ADDRESS, sw_interface_set_mac_address) \
65 _(SW_INTERFACE_GET_MAC_ADDRESS, sw_interface_get_mac_address) \
66 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
67 _(CREATE_SUBIF, create_subif) \
68 _(DELETE_SUBIF, delete_subif) \
69 _(CREATE_LOOPBACK, create_loopback) \
70 _(CREATE_LOOPBACK_INSTANCE, create_loopback_instance) \
71 _(DELETE_LOOPBACK, delete_loopback) \
72 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
73 _(COLLECT_DETAILED_INTERFACE_STATS, collect_detailed_interface_stats)
74 
75 static void
77 {
78  vl_api_sw_interface_set_flags_reply_t *rmp;
79  vnet_main_t *vnm = vnet_get_main ();
80  int rv = 0;
81  clib_error_t *error;
82  u16 flags;
83 
85 
87 
88  error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
89  if (error)
90  {
91  rv = -1;
92  clib_error_report (error);
93  }
94 
96  REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
97 }
98 
99 static void
101 {
102  vl_api_hw_interface_set_mtu_reply_t *rmp;
103  vnet_main_t *vnm = vnet_get_main ();
104  u32 sw_if_index = ntohl (mp->sw_if_index);
105  u16 mtu = ntohs (mp->mtu);
107  int rv = 0;
108 
110 
111  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
113  {
114  rv = VNET_API_ERROR_INVALID_VALUE;
115  goto bad_sw_if_index;
116  }
117 
120 
121  if (!eif)
122  {
123  rv = VNET_API_ERROR_FEATURE_DISABLED;
124  goto bad_sw_if_index;
125  }
126 
127  if (mtu < hi->min_supported_packet_bytes)
128  {
129  rv = VNET_API_ERROR_INVALID_VALUE;
130  goto bad_sw_if_index;
131  }
132 
133  if (mtu > hi->max_supported_packet_bytes)
134  {
135  rv = VNET_API_ERROR_INVALID_VALUE;
136  goto bad_sw_if_index;
137  }
138 
139  vnet_hw_interface_set_mtu (vnm, si->hw_if_index, mtu);
140 
142  REPLY_MACRO (VL_API_HW_INTERFACE_SET_MTU_REPLY);
143 }
144 
145 static void
147 {
148  vl_api_sw_interface_set_mtu_reply_t *rmp;
149  vnet_main_t *vnm = vnet_get_main ();
150  u32 sw_if_index = ntohl (mp->sw_if_index);
151  int rv = 0;
152  int i;
153  u32 per_protocol_mtu[VNET_N_MTU];
154 
156 
157  for (i = 0; i < VNET_N_MTU; i++)
158  per_protocol_mtu[i] = ntohl (mp->mtu[i]);
159 
160  vnet_sw_interface_set_protocol_mtu (vnm, sw_if_index, per_protocol_mtu);
161 
163  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MTU_REPLY);
164 }
165 
166 static void
169  vnet_sw_interface_t * swif,
170  u8 * interface_name, u32 context)
171 {
174 
175  vl_api_sw_interface_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
176  memset (mp, 0, sizeof (*mp));
177  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS);
178  mp->sw_if_index = ntohl (swif->sw_if_index);
179  mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index);
180  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
181  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
186  mp->link_mtu = ntohs (hi->max_packet_bytes);
187  mp->mtu[VNET_MTU_L3] = ntohl (swif->mtu[VNET_MTU_L3]);
188  mp->mtu[VNET_MTU_IP4] = ntohl (swif->mtu[VNET_MTU_IP4]);
189  mp->mtu[VNET_MTU_IP6] = ntohl (swif->mtu[VNET_MTU_IP6]);
190  mp->mtu[VNET_MTU_MPLS] = ntohl (swif->mtu[VNET_MTU_MPLS]);
191 
192  mp->context = context;
193 
194  strncpy ((char *) mp->interface_name,
195  (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
196 
197  /* Send the L2 address for ethernet physical intfcs */
198  if (swif->sup_sw_if_index == swif->sw_if_index
200  {
203 
204  ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
205  ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
206  clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
207  mp->l2_address_length = ntohl (sizeof (ei->address));
208  }
209  else if (swif->sup_sw_if_index != swif->sw_if_index)
210  {
211  vnet_sub_interface_t *sub = &swif->sub;
212  mp->sub_id = ntohl (sub->id);
213  mp->sub_dot1ad = sub->eth.flags.dot1ad;
214  mp->sub_number_of_tags =
215  sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
216  mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
217  mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
218  mp->sub_exact_match = sub->eth.flags.exact_match;
219  mp->sub_default = sub->eth.flags.default_sub;
220  mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
221  mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
222 
223  /* vlan tag rewrite data */
224  u32 vtr_op = L2_VTR_DISABLED;
225  u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
226 
227  if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
228  &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
229  {
230  // error - default to disabled
231  mp->vtr_op = ntohl (L2_VTR_DISABLED);
232  clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
233  swif->sw_if_index);
234  }
235  else
236  {
237  mp->vtr_op = ntohl (vtr_op);
238  mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
239  mp->vtr_tag1 = ntohl (vtr_tag1);
240  mp->vtr_tag2 = ntohl (vtr_tag2);
241  }
242  }
243 
244  /* pbb tag rewrite data */
245  ethernet_header_t eth_hdr;
246  u32 vtr_op = L2_VTR_DISABLED;
247  u16 outer_tag = 0;
248  u16 b_vlanid = 0;
249  u32 i_sid = 0;
250  memset (&eth_hdr, 0, sizeof (eth_hdr));
251 
252  if (!l2pbb_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
253  &vtr_op, &outer_tag, &eth_hdr, &b_vlanid, &i_sid))
254  {
255  mp->sub_dot1ah = 1;
256  clib_memcpy (mp->b_dmac, eth_hdr.dst_address,
257  sizeof (eth_hdr.dst_address));
258  clib_memcpy (mp->b_smac, eth_hdr.src_address,
259  sizeof (eth_hdr.src_address));
260  mp->b_vlanid = b_vlanid;
261  mp->i_sid = i_sid;
262  }
263 
265  if (tag)
266  strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
267 
268  vl_api_send_msg (rp, (u8 *) mp);
269 }
270 
271 static void
273 {
275  vnet_sw_interface_t *swif;
278 
280 
281  if (rp == 0)
282  {
283  clib_warning ("Client %d AWOL", mp->client_index);
284  return;
285  }
286 
287  u8 *filter = 0, *name = 0;
288  if (mp->name_filter_valid)
289  {
290  mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
291  filter = format (0, "%s%c", mp->name_filter, 0);
292  }
293 
294  char *strcasestr (char *, char *); /* lnx hdr file botch */
295  /* *INDENT-OFF* */
296  pool_foreach (swif, im->sw_interfaces,
297  ({
298  if (!vnet_swif_is_api_visible (swif))
299  continue;
300  vec_reset_length(name);
301  name = format (name, "%U%c", format_vnet_sw_interface_name, am->vnet_main,
302  swif, 0);
303 
304  if (filter && !strcasestr((char *) name, (char *) filter))
305  continue;
306 
307  send_sw_interface_details (am, rp, swif, name, mp->context);
308  }));
309  /* *INDENT-ON* */
310 
311  vec_free (name);
312  vec_free (filter);
313 }
314 
315 static void
318 {
319  vlib_main_t *vm = vlib_get_main ();
320  vnet_main_t *vnm = vnet_get_main ();
321  vl_api_sw_interface_add_del_address_reply_t *rmp;
322  int rv = 0;
323  u32 is_del;
324  clib_error_t *error = 0;
325 
327 
328  is_del = mp->is_add == 0;
329  vnm->api_errno = 0;
330 
331  if (mp->del_all)
333  else if (mp->is_ipv6)
334  error = ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
335  (void *) mp->address,
336  mp->address_length, is_del);
337  else
338  error = ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
339  (void *) mp->address,
340  mp->address_length, is_del);
341 
342  if (error)
343  {
344  rv = vnm->api_errno;
345  clib_error_report (error);
346  goto done;
347  }
348 
350 
351 done:
352  REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
353 }
354 
355 void stats_dslock_with_hint (int hint, int tag) __attribute__ ((weak));
356 void
357 stats_dslock_with_hint (int hint, int tag)
358 {
359 }
360 
361 void stats_dsunlock (void) __attribute__ ((weak));
362 void
364 {
365 }
366 
367 static void
369 {
370  vl_api_sw_interface_set_table_reply_t *rmp;
371  u32 sw_if_index = ntohl (mp->sw_if_index);
372  u32 table_id = ntohl (mp->vrf_id);
373  int rv = 0;
374 
376 
377  stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ );
378 
379  if (mp->is_ipv6)
380  rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, table_id, 1);
381  else
382  rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, table_id, 1);
383 
384  stats_dsunlock ();
385 
387 
388  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
389 }
390 
391 int
393  u32 sw_if_index, u32 table_id, u8 is_api)
394 {
396  u32 fib_index, mfib_index;
397  fib_source_t src;
398  mfib_source_t msrc;
399 
400  if (is_api)
401  {
402  src = FIB_SOURCE_API;
403  msrc = MFIB_SOURCE_API;
404  }
405  else
406  {
407  src = FIB_SOURCE_CLI;
408  msrc = MFIB_SOURCE_CLI;
409  }
410 
411  /*
412  * This if table does not exist = error is what we want in the end.
413  */
414  fib_index = fib_table_find (fproto, table_id);
415  mfib_index = mfib_table_find (fproto, table_id);
416 
417  if (~0 == fib_index || ~0 == mfib_index)
418  {
419  return (VNET_API_ERROR_NO_SUCH_FIB);
420  }
421 
422  if (FIB_PROTOCOL_IP6 == fproto)
423  {
424  /*
425  * If the interface already has in IP address, then a change int
426  * VRF is not allowed. The IP address applied must first be removed.
427  * We do not do that automatically here, since VPP has no knowledge
428  * of whether thoses subnets are valid in the destination VRF.
429  */
430  /* *INDENT-OFF* */
432  ia, sw_if_index,
433  1 /* honor unnumbered */ ,
434  ({
435  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
436  }));
437  /* *INDENT-ON* */
438 
441 
442  /*
443  * tell those that are interested that the binding is changing.
444  */
447  cb->function (&ip6_main, cb->function_opaque,
448  sw_if_index,
449  fib_index,
450  ip6_main.fib_index_by_sw_if_index[sw_if_index]);
451 
452  if (0 == table_id)
453  {
454  /* reset back to default */
455  if (0 != ip6_main.fib_index_by_sw_if_index[sw_if_index])
457  FIB_PROTOCOL_IP6, src);
458  if (0 != ip6_main.mfib_index_by_sw_if_index[sw_if_index])
460  [sw_if_index], FIB_PROTOCOL_IP6, msrc);
461 
462  }
463  else
464  {
465  /* we need to lock the table now it's inuse */
466  fib_table_lock (fib_index, FIB_PROTOCOL_IP6, src);
467  mfib_table_lock (mfib_index, FIB_PROTOCOL_IP6, msrc);
468  }
469 
470  ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
471  ip6_main.mfib_index_by_sw_if_index[sw_if_index] = mfib_index;
472  }
473  else
474  {
475  /*
476  * If the interface already has in IP address, then a change int
477  * VRF is not allowed. The IP address applied must first be removed.
478  * We do not do that automatically here, since VPP has no knowledge
479  * of whether thoses subnets are valid in the destination VRF.
480  */
481  /* *INDENT-OFF* */
483  ia, sw_if_index,
484  1 /* honor unnumbered */ ,
485  ({
486  return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE);
487  }));
488  /* *INDENT-ON* */
489 
492 
493  /*
494  * tell those that are interested that the binding is changing.
495  */
498  cb->function (&ip4_main, cb->function_opaque,
499  sw_if_index,
500  fib_index,
501  ip4_main.fib_index_by_sw_if_index[sw_if_index]);
502 
503  if (0 == table_id)
504  {
505  /* reset back to default */
506  if (0 != ip4_main.fib_index_by_sw_if_index[sw_if_index])
508  FIB_PROTOCOL_IP4, src);
509  if (0 != ip4_main.mfib_index_by_sw_if_index[sw_if_index])
511  [sw_if_index], FIB_PROTOCOL_IP4, msrc);
512 
513  }
514  else
515  {
516  /* we need to lock the table now it's inuse */
518  table_id, src);
519 
521  table_id, msrc);
522  }
523 
524  ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
525  ip4_main.mfib_index_by_sw_if_index[sw_if_index] = mfib_index;
526  }
527 
528  return (0);
529 }
530 
531 static void
533  u32 context, int retval, u32 vrf_id)
534 {
536 
537  mp = vl_msg_api_alloc (sizeof (*mp));
538  memset (mp, 0, sizeof (*mp));
539  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_GET_TABLE_REPLY);
540  mp->context = context;
541  mp->retval = htonl (retval);
542  mp->vrf_id = htonl (vrf_id);
543 
544  vl_api_send_msg (reg, (u8 *) mp);
545 }
546 
547 static void
549 {
551  fib_table_t *fib_table = 0;
552  u32 sw_if_index = ~0;
553  u32 fib_index = ~0;
554  u32 table_id = ~0;
555  fib_protocol_t fib_proto = FIB_PROTOCOL_IP4;
556  int rv = 0;
557 
559  if (!reg)
560  return;
561 
563 
564  sw_if_index = ntohl (mp->sw_if_index);
565 
566  if (mp->is_ipv6)
567  fib_proto = FIB_PROTOCOL_IP6;
568 
569  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
570  if (fib_index != ~0)
571  {
572  fib_table = fib_table_get (fib_index, fib_proto);
573  table_id = fib_table->ft_table_id;
574  }
575 
577 
578  send_sw_interface_get_table_reply (reg, mp->context, rv, table_id);
579 }
580 
583 {
584  vl_api_sw_interface_set_unnumbered_reply_t *rmp;
585  int rv = 0;
586  vnet_main_t *vnm = vnet_get_main ();
587  u32 sw_if_index = ntohl (mp->sw_if_index);
588  u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
589 
590  /*
591  * The API message field names are backwards from
592  * the underlying data structure names.
593  * It's not worth changing them now.
594  */
595  if (!vnet_sw_interface_is_api_valid (vnm, unnumbered_sw_if_index))
596  {
597  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
598  goto done;
599  }
600 
601  /* Only check the "use loop0" field when setting the binding */
602  if (mp->is_add && !vnet_sw_interface_is_api_valid (vnm, sw_if_index))
603  {
604  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
605  goto done;
606  }
607 
608  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
609  sw_if_index, mp->is_add);
610 done:
611  REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
612 }
613 
614 static void
616  mp)
617 {
618  vl_api_sw_interface_clear_stats_reply_t *rmp;
619 
620  vnet_main_t *vnm = vnet_get_main ();
624  static vnet_main_t **my_vnet_mains;
625  int i, j, n_counters;
626  int rv = 0;
627 
628  if (mp->sw_if_index != ~0)
630 
631  vec_reset_length (my_vnet_mains);
632 
633  for (i = 0; i < vec_len (vnet_mains); i++)
634  {
635  if (vnet_mains[i])
636  vec_add1 (my_vnet_mains, vnet_mains[i]);
637  }
638 
639  if (vec_len (vnet_mains) == 0)
640  vec_add1 (my_vnet_mains, vnm);
641 
642  n_counters = vec_len (im->combined_sw_if_counters);
643 
644  for (j = 0; j < n_counters; j++)
645  {
646  for (i = 0; i < vec_len (my_vnet_mains); i++)
647  {
648  im = &my_vnet_mains[i]->interface_main;
649  cm = im->combined_sw_if_counters + j;
650  if (mp->sw_if_index == (u32) ~ 0)
652  else
653  vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
654  }
655  }
656 
657  n_counters = vec_len (im->sw_if_counters);
658 
659  for (j = 0; j < n_counters; j++)
660  {
661  for (i = 0; i < vec_len (my_vnet_mains); i++)
662  {
663  im = &my_vnet_mains[i]->interface_main;
664  sm = im->sw_if_counters + j;
665  if (mp->sw_if_index == (u32) ~ 0)
667  else
668  vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
669  }
670  }
671 
673 
674  REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
675 }
676 
677 #define API_LINK_STATE_EVENT 1
678 #define API_ADMIN_UP_DOWN_EVENT 2
679 
680 static int
681 event_data_cmp (void *a1, void *a2)
682 {
683  uword *e1 = a1;
684  uword *e2 = a2;
685 
686  return (word) e1[0] - (word) e2[0];
687 }
688 
689 static void
692  vl_api_registration_t * vl_reg,
693  vnet_sw_interface_t * swif)
694 {
696  vnet_main_t *vnm = am->vnet_main;
697 
699  swif->sw_if_index);
700  mp = vl_msg_api_alloc (sizeof (*mp));
701  memset (mp, 0, sizeof (*mp));
702  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_EVENT);
703  mp->sw_if_index = ntohl (swif->sw_if_index);
704  mp->client_index = reg->client_index;
705  mp->pid = reg->client_pid;
706 
707  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
708  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
709  vl_api_send_msg (vl_reg, (u8 *) mp);
710 }
711 
712 static uword
715 {
717  vnet_main_t *vnm = vam->vnet_main;
718  vnet_sw_interface_t *swif;
719  uword *event_data = 0;
721  int i;
722  u32 prev_sw_if_index;
723  vl_api_registration_t *vl_reg;
724 
725  vam->link_state_process_up = 1;
726 
727  while (1)
728  {
730 
731  /* Unified list of changed link or admin state sw_if_indices */
733  (vm, &event_data, API_LINK_STATE_EVENT);
735  (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
736 
737  /* Sort, so we can eliminate duplicates */
739 
740  prev_sw_if_index = ~0;
741 
742  for (i = 0; i < vec_len (event_data); i++)
743  {
744  /* Only one message per swif */
745  if (prev_sw_if_index == event_data[i])
746  continue;
747  prev_sw_if_index = event_data[i];
748 
749  /* *INDENT-OFF* */
750  pool_foreach(reg, vam->interface_events_registrations,
751  ({
752  vl_reg = vl_api_client_index_to_registration (reg->client_index);
753  if (vl_reg)
754  {
755  /* sw_interface may be deleted already */
756  if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
757  event_data[i]))
758  {
759  swif = vnet_get_sw_interface (vnm, event_data[i]);
760  send_sw_interface_event (vam, reg, vl_reg, swif);
761  }
762  }
763  }));
764  /* *INDENT-ON* */
765  }
766  vec_reset_length (event_data);
767  }
768 
769  return 0;
770 }
771 
772 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
773  u32 flags);
775  u32 hw_if_index, u32 flags);
776 
777 /* *INDENT-OFF* */
778 VLIB_REGISTER_NODE (link_state_process_node,static) = {
779  .function = link_state_process,
780  .type = VLIB_NODE_TYPE_PROCESS,
781  .name = "vpe-link-state-process",
782 };
783 /* *INDENT-ON* */
784 
785 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
786 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_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)
796  link_state_process_node.index,
798  return 0;
799 }
800 
801 static clib_error_t *
802 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
803 {
805 
806  /*
807  * Note: it's perfectly fair to set a subif admin up / admin down.
808  * Note the subtle distinction between this routine and the previous
809  * routine.
810  */
811  if (vam->link_state_process_up)
813  link_state_process_node.index,
814  API_ADMIN_UP_DOWN_EVENT, sw_if_index);
815  return 0;
816 }
817 
820 {
821  vnet_main_t *vnm = vnet_get_main ();
822  vl_api_sw_interface_tag_add_del_reply_t *rmp;
823  int rv = 0;
824  u8 *tag;
825  u32 sw_if_index = ntohl (mp->sw_if_index);
826 
828 
829  if (mp->is_add)
830  {
831  if (mp->tag[0] == 0)
832  {
833  rv = VNET_API_ERROR_INVALID_VALUE;
834  goto out;
835  }
836 
837  mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
838  tag = format (0, "%s%c", mp->tag, 0);
839  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
840  }
841  else
842  vnet_clear_sw_interface_tag (vnm, sw_if_index);
843 
845 out:
846  REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY);
847 }
848 
851 {
852  vl_api_sw_interface_set_mac_address_reply_t *rmp;
853  vnet_main_t *vnm = vnet_get_main ();
854  u32 sw_if_index = ntohl (mp->sw_if_index);
856  clib_error_t *error;
857  int rv = 0;
858 
860 
861  si = vnet_get_sw_interface (vnm, sw_if_index);
863  mp->mac_address);
864  if (error)
865  {
866  rv = VNET_API_ERROR_UNIMPLEMENTED;
867  clib_error_report (error);
868  goto out;
869  }
870 
872 out:
873  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
874 }
875 
878 {
881  vnet_main_t *vnm = vnet_get_main ();
882  u32 sw_if_index = ntohl (mp->sw_if_index);
884  ethernet_interface_t *eth_if = 0;
885  int rv = 0;
886 
888 
889  si = vnet_get_sup_sw_interface (vnm, sw_if_index);
892 
894 
896  if (!reg)
897  return;
898  rmp = vl_msg_api_alloc (sizeof (*rmp));
899  rmp->_vl_msg_id = htons (VL_API_SW_INTERFACE_GET_MAC_ADDRESS_REPLY);
900  rmp->context = mp->context;
901  rmp->retval = htonl (rv);
902  if (!rv && eth_if)
903  memcpy (rmp->mac_address, eth_if->address, 6);
904  vl_api_send_msg (reg, (u8 *) rmp);
905 }
906 
909 {
910  vl_api_sw_interface_set_rx_mode_reply_t *rmp;
911  vnet_main_t *vnm = vnet_get_main ();
912  u32 sw_if_index = ntohl (mp->sw_if_index);
914  clib_error_t *error;
915  int rv = 0;
916 
918 
919  si = vnet_get_sw_interface (vnm, sw_if_index);
921  mp->queue_id_valid,
922  ntohl (mp->queue_id), mp->mode);
923  if (error)
924  {
925  rv = VNET_API_ERROR_UNIMPLEMENTED;
926  clib_error_report (error);
927  goto out;
928  }
929 
931 out:
932  REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
933 }
934 
935 static void
937 {
939  vnet_main_t *vnm = vnet_get_main ();
940  u32 sw_if_index = (u32) ~ 0;
942  int rv = 0;
943  u32 id;
944  vnet_sw_interface_t template;
945  uword *p;
947  u64 sup_and_sub_key;
949  clib_error_t *error;
950 
952 
953  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
954 
956  {
957  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
958  goto out;
959  }
960 
961  id = ntohl (mp->vlan_id);
962  if (id == 0 || id > 4095)
963  {
964  rv = VNET_API_ERROR_INVALID_VLAN;
965  goto out;
966  }
967 
968  sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
969 
970  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
971  if (p)
972  {
973  rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
974  goto out;
975  }
976 
977  memset (&template, 0, sizeof (template));
978  template.type = VNET_SW_INTERFACE_TYPE_SUB;
979  template.sup_sw_if_index = hi->sw_if_index;
980  template.sub.id = id;
981  template.sub.eth.raw_flags = 0;
982  template.sub.eth.flags.one_tag = 1;
983  template.sub.eth.outer_vlan_id = id;
984  template.sub.eth.flags.exact_match = 1;
985 
986  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
987  if (error)
988  {
989  clib_error_report (error);
990  rv = VNET_API_ERROR_INVALID_REGISTRATION;
991  goto out;
992  }
993 
994  u64 *kp = clib_mem_alloc (sizeof (*kp));
995  *kp = sup_and_sub_key;
996 
997  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
998  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
999 
1001 
1002 out:
1004  if (!reg)
1005  return;
1006 
1007  rmp = vl_msg_api_alloc (sizeof (*rmp));
1008  rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
1009  rmp->context = mp->context;
1010  rmp->retval = htonl (rv);
1011  rmp->sw_if_index = htonl (sw_if_index);
1012  vl_api_send_msg (reg, (u8 *) rmp);
1013 }
1014 
1015 static void
1017 {
1019  vnet_main_t *vnm = vnet_get_main ();
1020  u32 sw_if_index = ~0;
1021  int rv = 0;
1022  u32 sub_id;
1023  vnet_sw_interface_t *si;
1025  vnet_sw_interface_t template;
1026  uword *p;
1028  u64 sup_and_sub_key;
1029  clib_error_t *error;
1030 
1031  VALIDATE_SW_IF_INDEX (mp);
1032 
1033  si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1034  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1035 
1037  {
1038  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1039  goto out;
1040  }
1041 
1042  sw_if_index = si->sw_if_index;
1043  sub_id = ntohl (mp->sub_id);
1044 
1045  sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1046 
1047  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1048  if (p)
1049  {
1050  if (CLIB_DEBUG > 0)
1051  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1052  sw_if_index, sub_id);
1053  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1054  goto out;
1055  }
1056 
1057  memset (&template, 0, sizeof (template));
1058  template.type = VNET_SW_INTERFACE_TYPE_SUB;
1059  template.sup_sw_if_index = sw_if_index;
1060  template.sub.id = sub_id;
1061  template.sub.eth.flags.no_tags = mp->no_tags;
1062  template.sub.eth.flags.one_tag = mp->one_tag;
1063  template.sub.eth.flags.two_tags = mp->two_tags;
1064  template.sub.eth.flags.dot1ad = mp->dot1ad;
1065  template.sub.eth.flags.exact_match = mp->exact_match;
1066  template.sub.eth.flags.default_sub = mp->default_sub;
1067  template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1068  template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1069  template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1070  template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1071 
1072  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1073  if (error)
1074  {
1075  clib_error_report (error);
1076  rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1077  goto out;
1078  }
1079 
1080  u64 *kp = clib_mem_alloc (sizeof (*kp));
1081  *kp = sup_and_sub_key;
1082 
1083  hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1084  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1085 
1087 
1088 out:
1089 
1090  /* *INDENT-OFF* */
1091  REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1092  ({
1093  rmp->sw_if_index = ntohl(sw_if_index);
1094  }));
1095  /* *INDENT-ON* */
1096 }
1097 
1098 static void
1100 {
1101  vl_api_delete_subif_reply_t *rmp;
1102  int rv;
1103 
1104  rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
1105 
1106  REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
1107 }
1108 
1109 static void
1111  mp)
1112 {
1113  vl_api_interface_name_renumber_reply_t *rmp;
1114  int rv = 0;
1115 
1116  VALIDATE_SW_IF_INDEX (mp);
1117 
1119  (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
1120 
1122 
1123  REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
1124 }
1125 
1126 static void
1128 {
1130  u32 sw_if_index;
1131  int rv;
1132 
1133  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address, 0, 0);
1134 
1135  /* *INDENT-OFF* */
1136  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
1137  ({
1138  rmp->sw_if_index = ntohl (sw_if_index);
1139  }));
1140  /* *INDENT-ON* */
1141 }
1142 
1145 {
1147  u32 sw_if_index;
1148  u8 is_specified = mp->is_specified;
1149  u32 user_instance = ntohl (mp->user_instance);
1150  int rv;
1151 
1152  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address,
1153  is_specified, user_instance);
1154 
1155  /* *INDENT-OFF* */
1156  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_INSTANCE_REPLY,
1157  ({
1158  rmp->sw_if_index = ntohl (sw_if_index);
1159  }));
1160  /* *INDENT-ON* */
1161 }
1162 
1163 static void
1165 {
1166  vl_api_delete_loopback_reply_t *rmp;
1167  u32 sw_if_index;
1168  int rv;
1169 
1170  sw_if_index = ntohl (mp->sw_if_index);
1171  rv = vnet_delete_loopback_interface (sw_if_index);
1172 
1173  REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
1174 }
1175 
1176 static void
1179 {
1180  vl_api_collect_detailed_interface_stats_reply_t *rmp;
1181  int rv = 0;
1182 
1183  rv =
1185  mp->enable_disable);
1186 
1187  REPLY_MACRO (VL_API_COLLECT_DETAILED_INTERFACE_STATS_REPLY);
1188 }
1189 
1190 /*
1191  * vpe_api_hookup
1192  * Add vpe's API message handlers to the table.
1193  * vlib has alread mapped shared memory and
1194  * added the client registration handlers.
1195  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1196  */
1197 #define vl_msg_name_crc_list
1198 #include <vnet/interface.api.h>
1199 #undef vl_msg_name_crc_list
1200 
1201 static void
1203 {
1204 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1205  foreach_vl_msg_name_crc_interface;
1206 #undef _
1207 }
1208 
1209 pub_sub_handler (interface_events, INTERFACE_EVENTS);
1210 
1211 static clib_error_t *
1213 {
1214  api_main_t *am = &api_main;
1215 
1216 #define _(N,n) \
1217  vl_msg_api_set_handlers(VL_API_##N, #n, \
1218  vl_api_##n##_t_handler, \
1219  vl_noop_handler, \
1220  vl_api_##n##_t_endian, \
1221  vl_api_##n##_t_print, \
1222  sizeof(vl_api_##n##_t), 1);
1224 #undef _
1225 
1226  /*
1227  * Set up the (msg_name, crc, message-id) table
1228  */
1230 
1231  return 0;
1232 }
1233 
1235 
1236 /*
1237  * fd.io coding-style-patch-verification: ON
1238  *
1239  * Local Variables:
1240  * eval: (c-set-style "gnu")
1241  * End:
1242  */
static void vl_api_delete_subif_t_handler(vl_api_delete_subif_t *mp)
#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:179
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
ip4_table_bind_function_t * function
Definition: ip4.h:82
vnet_main_t * vnet_main
#define CLIB_UNUSED(x)
Definition: clib.h:79
Enable or disable detailed interface stats.
Definition: interface.api:565
Get interface&#39;s MAC address.
Definition: interface.api:382
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:948
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
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:74
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:1373
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:97
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:543
vlib_main_t * vlib_main
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:111
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)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:458
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
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
#define VNET_HW_INTERFACE_FLAG_DUPLEX_MASK
Definition: interface.h:463
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:481
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:114
Set an interface&#39;s rx-mode.
Definition: interface.api:411
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:340
i64 word
Definition: types.h:111
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:810
u8 dst_address[6]
Definition: packet.h:55
Reply for the vlan subinterface create request.
Definition: interface.api:476
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:226
u32 mtu[VNET_N_MTU]
Definition: interface.h:694
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:1056
A collection of simple counters.
Definition: counter.h:58
void vnet_sw_interface_set_protocol_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu[])
Definition: interface.c:688
u32 max_supported_packet_bytes
Definition: interface.h:534
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:631
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:460
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
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:278
vnet_sub_interface_t sub
Definition: interface.h:697
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:952
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:468
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:804
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:238
#define REPLY_MACRO(t)
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:539
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:809
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:1490
void ip_del_all_interface_addresses(vlib_main_t *vm, u32 sw_if_index)
Definition: ip46_cli.c:82
Set or delete one or all ip addresses on a specified interface.
Definition: interface.api:193
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:1228
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
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:557
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:554
#define BAD_SW_IF_INDEX_LABEL
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
static void vl_api_sw_interface_set_flags_t_handler(vl_api_sw_interface_set_flags_t *mp)
Definition: interface_api.c:76
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)
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:740
#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:713
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:1481
#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:488
#define ARRAY_LEN(x)
Definition: clib.h:59
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)
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:551
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(admin_up_down_function)
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
Definition: fib_table.c:1257
foreach_registration_hash u8 link_state_process_up
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:660
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:394
ip6_main_t ip6_main
Definition: ip6_forward.c:2574
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:1115
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:124
static u8 * vnet_get_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
From the control plane API.
Definition: fib_entry.h:70
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:112
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
Interface Event generated by want_interface_events.
Definition: interface.api:57
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:132
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:720
static void vl_api_create_subif_t_handler(vl_api_create_subif_t *mp)
Create loopback interface instance request.
Definition: interface.api:525
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:703
#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:961
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:801
Create loopback interface request.
Definition: interface.api:499
ip6_table_bind_function_t * function
Definition: ip6.h:115
Set unnumbered interface add / del request.
Definition: interface.api:326
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:181
Create a new subinterface with the given vlan id.
Definition: interface.api:463
int vnet_sw_interface_stats_collect_enable_disable(u32 sw_if_index, u8 enable)
Create loopback interface response.
Definition: interface.api:511
#define hash_get_mem(h, key)
Definition: hash.h:269
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:369
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:655
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:832
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:549
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
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:601
Interface details structure (fix this)
Definition: interface.api:110
static void vl_api_sw_interface_set_table_t_handler(vl_api_sw_interface_set_table_t *mp)
u32 flags
Definition: vhost-user.h:77
Set / clear software interface tag.
Definition: interface.api:354
ethernet_interface_t * interfaces
Definition: ethernet.h:278
Associate the specified interface with a fib table.
Definition: interface.api:212
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