FD.io VPP  v17.07.01-10-g3be13f0
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 _(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) \
54 _(WANT_INTERFACE_EVENTS, want_interface_events) \
55 _(SW_INTERFACE_DUMP, sw_interface_dump) \
56 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
57 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
58 _(SW_INTERFACE_GET_TABLE, sw_interface_get_table) \
59 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
60 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
61 _(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) \
62 _(SW_INTERFACE_SET_MAC_ADDRESS, sw_interface_set_mac_address)
63 
64 static void
66 {
67  vl_api_sw_interface_set_flags_reply_t *rmp;
68  vnet_main_t *vnm = vnet_get_main ();
69  int rv = 0;
70  clib_error_t *error;
71  u16 flags;
72 
74 
76 
77  error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
78  if (error)
79  {
80  rv = -1;
81  clib_error_report (error);
82  }
83 
85  REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
86 }
87 
88 static void
90 {
91  vl_api_sw_interface_set_mtu_reply_t *rmp;
92  vnet_main_t *vnm = vnet_get_main ();
94  u32 sw_if_index = ntohl (mp->sw_if_index);
95  u16 mtu = ntohs (mp->mtu);
97  int rv = 0;
98 
100 
101  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
103  {
104  rv = VNET_API_ERROR_INVALID_VALUE;
105  goto bad_sw_if_index;
106  }
107 
110 
111  if (!eif)
112  {
113  rv = VNET_API_ERROR_FEATURE_DISABLED;
114  goto bad_sw_if_index;
115  }
116 
117  if (mtu < hi->min_supported_packet_bytes)
118  {
119  rv = VNET_API_ERROR_INVALID_VALUE;
120  goto bad_sw_if_index;
121  }
122 
123  if (mtu > hi->max_supported_packet_bytes)
124  {
125  rv = VNET_API_ERROR_INVALID_VALUE;
126  goto bad_sw_if_index;
127  }
128 
129  if (hi->max_packet_bytes != mtu)
130  {
131  hi->max_packet_bytes = mtu;
132  ethernet_set_flags (vnm, si->hw_if_index, flags);
133  }
134 
136  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MTU_REPLY);
137 }
138 
139 static void
142  vnet_sw_interface_t * swif,
143  u8 * interface_name, u32 context)
144 {
147 
148  vl_api_sw_interface_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
149  memset (mp, 0, sizeof (*mp));
150  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS);
151  mp->sw_if_index = ntohl (swif->sw_if_index);
152  mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index);
153  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
154  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
159  mp->link_mtu = ntohs (hi->max_packet_bytes);
160  mp->context = context;
161 
162  strncpy ((char *) mp->interface_name,
163  (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
164 
165  /* Send the L2 address for ethernet physical intfcs */
166  if (swif->sup_sw_if_index == swif->sw_if_index
168  {
171 
172  ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
173  ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
174  clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
175  mp->l2_address_length = ntohl (sizeof (ei->address));
176  }
177  else if (swif->sup_sw_if_index != swif->sw_if_index)
178  {
179  vnet_sub_interface_t *sub = &swif->sub;
180  mp->sub_id = ntohl (sub->id);
181  mp->sub_dot1ad = sub->eth.flags.dot1ad;
182  mp->sub_number_of_tags =
183  sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
184  mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
185  mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
186  mp->sub_exact_match = sub->eth.flags.exact_match;
187  mp->sub_default = sub->eth.flags.default_sub;
188  mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
189  mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
190 
191  /* vlan tag rewrite data */
192  u32 vtr_op = L2_VTR_DISABLED;
193  u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
194 
195  if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
196  &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
197  {
198  // error - default to disabled
199  mp->vtr_op = ntohl (L2_VTR_DISABLED);
200  clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
201  swif->sw_if_index);
202  }
203  else
204  {
205  mp->vtr_op = ntohl (vtr_op);
206  mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
207  mp->vtr_tag1 = ntohl (vtr_tag1);
208  mp->vtr_tag2 = ntohl (vtr_tag2);
209  }
210  }
211 
212  /* pbb tag rewrite data */
213  ethernet_header_t eth_hdr;
214  u32 vtr_op = L2_VTR_DISABLED;
215  u16 outer_tag = 0;
216  u16 b_vlanid = 0;
217  u32 i_sid = 0;
218  memset (&eth_hdr, 0, sizeof (eth_hdr));
219 
220  if (!l2pbb_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
221  &vtr_op, &outer_tag, &eth_hdr, &b_vlanid, &i_sid))
222  {
223  mp->sub_dot1ah = 1;
224  clib_memcpy (mp->b_dmac, eth_hdr.dst_address,
225  sizeof (eth_hdr.dst_address));
226  clib_memcpy (mp->b_smac, eth_hdr.src_address,
227  sizeof (eth_hdr.src_address));
228  mp->b_vlanid = b_vlanid;
229  mp->i_sid = i_sid;
230  }
231 
233  if (tag)
234  strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
235 
236  vl_msg_api_send_shmem (q, (u8 *) & mp);
237 }
238 
239 static void
241 {
243  vnet_sw_interface_t *swif;
245 
248  if (q == 0)
249  return;
250 
251  u8 *filter = 0, *name = 0;
252  if (mp->name_filter_valid)
253  {
254  mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
255  filter = format (0, "%s%c", mp->name_filter, 0);
256  }
257 
258  char *strcasestr (char *, char *); /* lnx hdr file botch */
259  /* *INDENT-OFF* */
260  pool_foreach (swif, im->sw_interfaces,
261  ({
262  if (!vnet_swif_is_api_visible (swif))
263  continue;
264  vec_reset_length(name);
265  name = format (name, "%U%c", format_vnet_sw_interface_name, am->vnet_main,
266  swif, 0);
267 
268  if (filter && !strcasestr((char *) name, (char *) filter))
269  continue;
270 
271  send_sw_interface_details (am, q, swif, name, mp->context);
272  }));
273  /* *INDENT-ON* */
274 
275  vec_free (name);
276  vec_free (filter);
277 }
278 
279 static void
282 {
283  vlib_main_t *vm = vlib_get_main ();
284  vl_api_sw_interface_add_del_address_reply_t *rmp;
285  int rv = 0;
286  u32 is_del;
287 
289 
290  is_del = mp->is_add == 0;
291 
292  if (mp->del_all)
294  else if (mp->is_ipv6)
296  (void *) mp->address,
297  mp->address_length, is_del);
298  else
300  (void *) mp->address,
301  mp->address_length, is_del);
302 
304 
305  REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
306 }
307 
308 void stats_dslock_with_hint (int hint, int tag) __attribute__ ((weak));
309 void
310 stats_dslock_with_hint (int hint, int tag)
311 {
312 }
313 
314 void stats_dsunlock (void) __attribute__ ((weak));
315 void
317 {
318 }
319 
320 static void
322 {
323  int rv = 0;
324  u32 table_id = ntohl (mp->vrf_id);
325  u32 sw_if_index = ntohl (mp->sw_if_index);
326  vl_api_sw_interface_set_table_reply_t *rmp;
328  u32 fib_index;
329 
331 
332  stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ );
333 
334  if (mp->is_ipv6)
335  {
336  /* *INDENT-OFF* */
338  ia, sw_if_index,
339  1 /* honor unnumbered */ ,
340  ({
341  rv = VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE;
342  goto done;
343  }));
344  /* *INDENT-ON* */
345 
347  table_id);
349  ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
350 
352  table_id);
354  ip6_main.mfib_index_by_sw_if_index[sw_if_index] = fib_index;
355  }
356  else
357  {
358  /* *INDENT-OFF* */
360  ia, sw_if_index,
361  1 /* honor unnumbered */ ,
362  ({
363  rv = VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE;
364  goto done;
365  }));
366  /* *INDENT-ON* */
367 
369  table_id);
371  ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
372 
374  table_id);
376  ip4_main.mfib_index_by_sw_if_index[sw_if_index] = fib_index;
377  }
378 
379 done:
380  stats_dsunlock ();
381 
383 
384  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
385 }
386 
387 static void
389  u32 context, int retval, u32 vrf_id)
390 {
392 
393  mp = vl_msg_api_alloc (sizeof (*mp));
394  memset (mp, 0, sizeof (*mp));
395  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_GET_TABLE_REPLY);
396  mp->context = context;
397  mp->retval = htonl (retval);
398  mp->vrf_id = htonl (vrf_id);
399 
400  vl_msg_api_send_shmem (q, (u8 *) & mp);
401 }
402 
403 static void
405 {
407  fib_table_t *fib_table = 0;
408  u32 sw_if_index = ~0;
409  u32 fib_index = ~0;
410  u32 table_id = ~0;
411  fib_protocol_t fib_proto = FIB_PROTOCOL_IP4;
412  int rv = 0;
413 
415  if (q == 0)
416  return;
417 
419 
420  sw_if_index = ntohl (mp->sw_if_index);
421 
422  if (mp->is_ipv6)
423  fib_proto = FIB_PROTOCOL_IP6;
424 
425  fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
426  if (fib_index != ~0)
427  {
428  fib_table = fib_table_get (fib_index, fib_proto);
429  table_id = fib_table->ft_table_id;
430  }
431 
433 
434  send_sw_interface_get_table_reply (q, mp->context, rv, table_id);
435 }
436 
439 {
440  vl_api_sw_interface_set_unnumbered_reply_t *rmp;
441  int rv = 0;
442  vnet_main_t *vnm = vnet_get_main ();
443  u32 sw_if_index = ntohl (mp->sw_if_index);
444  u32 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
445  u32 was_unnum;
446 
447  /*
448  * The API message field names are backwards from
449  * the underlying data structure names.
450  * It's not worth changing them now.
451  */
452  if (!vnet_sw_interface_is_api_valid (vnm, unnumbered_sw_if_index))
453  {
454  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
455  goto done;
456  }
457 
458  /* Only check the "use loop0" field when setting the binding */
459  if (mp->is_add && !vnet_sw_interface_is_api_valid (vnm, sw_if_index))
460  {
461  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
462  goto done;
463  }
464 
465  vnet_sw_interface_t *si =
466  vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
467  was_unnum = (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED);
468 
469  if (mp->is_add)
470  {
472  si->unnumbered_sw_if_index = sw_if_index;
473 
475  [unnumbered_sw_if_index] =
476  ip4_main.
477  lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index];
478  ip6_main.
479  lookup_main.if_address_pool_index_by_sw_if_index
480  [unnumbered_sw_if_index] =
481  ip6_main.
482  lookup_main.if_address_pool_index_by_sw_if_index[sw_if_index];
483  }
484  else
485  {
487  si->unnumbered_sw_if_index = (u32) ~ 0;
488 
490  [unnumbered_sw_if_index] = ~0;
492  [unnumbered_sw_if_index] = ~0;
493  }
494 
495  if (was_unnum != (si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
496  {
497  ip4_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add);
498  ip6_sw_interface_enable_disable (unnumbered_sw_if_index, mp->is_add);
499  }
500 
501 done:
502  REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
503 }
504 
505 static void
507  mp)
508 {
509  vl_api_sw_interface_clear_stats_reply_t *rmp;
510 
511  vnet_main_t *vnm = vnet_get_main ();
515  static vnet_main_t **my_vnet_mains;
516  int i, j, n_counters;
517  int rv = 0;
518 
519  if (mp->sw_if_index != ~0)
521 
522  vec_reset_length (my_vnet_mains);
523 
524  for (i = 0; i < vec_len (vnet_mains); i++)
525  {
526  if (vnet_mains[i])
527  vec_add1 (my_vnet_mains, vnet_mains[i]);
528  }
529 
530  if (vec_len (vnet_mains) == 0)
531  vec_add1 (my_vnet_mains, vnm);
532 
533  n_counters = vec_len (im->combined_sw_if_counters);
534 
535  for (j = 0; j < n_counters; j++)
536  {
537  for (i = 0; i < vec_len (my_vnet_mains); i++)
538  {
539  im = &my_vnet_mains[i]->interface_main;
540  cm = im->combined_sw_if_counters + j;
541  if (mp->sw_if_index == (u32) ~ 0)
543  else
544  vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
545  }
546  }
547 
548  n_counters = vec_len (im->sw_if_counters);
549 
550  for (j = 0; j < n_counters; j++)
551  {
552  for (i = 0; i < vec_len (my_vnet_mains); i++)
553  {
554  im = &my_vnet_mains[i]->interface_main;
555  sm = im->sw_if_counters + j;
556  if (mp->sw_if_index == (u32) ~ 0)
558  else
559  vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
560  }
561  }
562 
564 
565  REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
566 }
567 
568 #define API_LINK_STATE_EVENT 1
569 #define API_ADMIN_UP_DOWN_EVENT 2
570 
571 static int
572 event_data_cmp (void *a1, void *a2)
573 {
574  uword *e1 = a1;
575  uword *e2 = a2;
576 
577  return (word) e1[0] - (word) e2[0];
578 }
579 
580 static void
583  vnet_sw_interface_t * swif)
584 {
586  vnet_main_t *vnm = am->vnet_main;
587 
589  swif->sw_if_index);
590  mp = vl_msg_api_alloc (sizeof (*mp));
591  memset (mp, 0, sizeof (*mp));
592  mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
593  mp->sw_if_index = ntohl (swif->sw_if_index);
594 
595  mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
596  mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
597  vl_msg_api_send_shmem (q, (u8 *) & mp);
598 }
599 
600 static uword
603 {
605  vnet_main_t *vnm = vam->vnet_main;
606  vnet_sw_interface_t *swif;
607  uword *event_data = 0;
609  int i;
610  u32 prev_sw_if_index;
612 
613  vam->link_state_process_up = 1;
614 
615  while (1)
616  {
618 
619  /* Unified list of changed link or admin state sw_if_indices */
621  (vm, &event_data, API_LINK_STATE_EVENT);
623  (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
624 
625  /* Sort, so we can eliminate duplicates */
627 
628  prev_sw_if_index = ~0;
629 
630  for (i = 0; i < vec_len (event_data); i++)
631  {
632  /* Only one message per swif */
633  if (prev_sw_if_index == event_data[i])
634  continue;
635  prev_sw_if_index = event_data[i];
636 
637  /* *INDENT-OFF* */
638  pool_foreach(reg, vam->interface_events_registrations,
639  ({
640  q = vl_api_client_index_to_input_queue (reg->client_index);
641  if (q)
642  {
643  /* sw_interface may be deleted already */
644  if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
645  event_data[i]))
646  {
647  swif = vnet_get_sw_interface (vnm, event_data[i]);
648  send_sw_interface_flags (vam, q, swif);
649  }
650  }
651  }));
652  /* *INDENT-ON* */
653  }
654  vec_reset_length (event_data);
655  }
656 
657  return 0;
658 }
659 
660 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
661  u32 flags);
663  u32 hw_if_index, u32 flags);
664 
665 /* *INDENT-OFF* */
666 VLIB_REGISTER_NODE (link_state_process_node,static) = {
667  .function = link_state_process,
668  .type = VLIB_NODE_TYPE_PROCESS,
669  .name = "vpe-link-state-process",
670 };
671 /* *INDENT-ON* */
672 
673 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
674 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
675 
676 static clib_error_t *
677 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
678 {
680  vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
681 
682  if (vam->link_state_process_up)
684  link_state_process_node.index,
686  return 0;
687 }
688 
689 static clib_error_t *
690 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
691 {
693 
694  /*
695  * Note: it's perfectly fair to set a subif admin up / admin down.
696  * Note the subtle distinction between this routine and the previous
697  * routine.
698  */
699  if (vam->link_state_process_up)
701  link_state_process_node.index,
702  API_ADMIN_UP_DOWN_EVENT, sw_if_index);
703  return 0;
704 }
705 
708 {
709  vnet_main_t *vnm = vnet_get_main ();
710  vl_api_sw_interface_tag_add_del_reply_t *rmp;
711  int rv = 0;
712  u8 *tag;
713  u32 sw_if_index = ntohl (mp->sw_if_index);
714 
716 
717  if (mp->is_add)
718  {
719  if (mp->tag[0] == 0)
720  {
721  rv = VNET_API_ERROR_INVALID_VALUE;
722  goto out;
723  }
724 
725  mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
726  tag = format (0, "%s%c", mp->tag, 0);
727  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
728  }
729  else
730  vnet_clear_sw_interface_tag (vnm, sw_if_index);
731 
733 out:
734  REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY);
735 }
736 
739 {
740  vl_api_sw_interface_set_mac_address_reply_t *rmp;
741  vnet_main_t *vnm = vnet_get_main ();
742  u32 sw_if_index = ntohl (mp->sw_if_index);
744  u64 mac;
745  clib_error_t *error;
746  int rv = 0;
747 
749 
750  mac = ((u64) mp->mac_address[0] << (8 * 0)
751  | (u64) mp->mac_address[1] << (8 * 1)
752  | (u64) mp->mac_address[2] << (8 * 2)
753  | (u64) mp->mac_address[3] << (8 * 3)
754  | (u64) mp->mac_address[4] << (8 * 4)
755  | (u64) mp->mac_address[5] << (8 * 5));
756 
757  si = vnet_get_sw_interface (vnm, sw_if_index);
758  error = vnet_hw_interface_change_mac_address (vnm, si->hw_if_index, mac);
759  if (error)
760  {
761  rv = VNET_API_ERROR_UNIMPLEMENTED;
762  clib_error_report (error);
763  goto out;
764  }
765 
767 out:
768  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY);
769 }
770 
771 /*
772  * vpe_api_hookup
773  * Add vpe's API message handlers to the table.
774  * vlib has alread mapped shared memory and
775  * added the client registration handlers.
776  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
777  */
778 #define vl_msg_name_crc_list
779 #include <vnet/interface.api.h>
780 #undef vl_msg_name_crc_list
781 
782 static void
784 {
785 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
786  foreach_vl_msg_name_crc_interface;
787 #undef _
788 }
789 
790 pub_sub_handler (interface_events, INTERFACE_EVENTS);
791 
792 static clib_error_t *
794 {
795  api_main_t *am = &api_main;
796 
797 #define _(N,n) \
798  vl_msg_api_set_handlers(VL_API_##N, #n, \
799  vl_api_##n##_t_handler, \
800  vl_noop_handler, \
801  vl_api_##n##_t_endian, \
802  vl_api_##n##_t_print, \
803  sizeof(vl_api_##n##_t), 1);
805 #undef _
806 
807  /*
808  * Set up the (msg_name, crc, message-id) table
809  */
811 
812  return 0;
813 }
814 
816 
817 /*
818  * fd.io coding-style-patch-verification: ON
819  *
820  * Local Variables:
821  * eval: (c-set-style "gnu")
822  * End:
823  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:179
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:567
static int event_data_cmp(void *a1, void *a2)
vmrglw vmrglh hi
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
vnet_main_t * vnet_main
#define CLIB_UNUSED(x)
Definition: clib.h:79
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:166
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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:9
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)
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, u64 mac_address)
Definition: interface.c:1374
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:929
u8 src_address[6]
Definition: packet.h:54
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t ** vnet_mains
Definition: vnet.h:82
add_epi add_epi sub
Definition: vector_sse2.h:283
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
static void vnet_clear_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
VLIB_API_INIT_FUNCTION(interface_api_hookup)
ip_lookup_main_t lookup_main
Definition: ip4.h:85
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vlib_main
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:99
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:397
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
static void send_sw_interface_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, vnet_sw_interface_t *swif, u8 *interface_name, u32 context)
static void vl_api_sw_interface_dump_t_handler(vl_api_sw_interface_dump_t *mp)
#define VNET_HW_INTERFACE_FLAG_DUPLEX_MASK
Definition: interface.h:402
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)
static void send_sw_interface_get_table_reply(unix_shared_memory_queue_t *q, u32 context, int retval, u32 vrf_id)
#define VNET_HW_INTERFACE_FLAG_SPEED_MASK
Definition: interface.h:414
ethernet_main_t ethernet_main
Definition: ethernet.h:273
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:102
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:268
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:653
u8 dst_address[6]
Definition: packet.h:53
Get VRF id assigned to interface.
Definition: interface.api:190
unsigned long u64
Definition: types.h:89
A collection of simple counters.
Definition: counter.h:58
void * vl_msg_api_alloc(int nbytes)
u32 max_supported_packet_bytes
Definition: interface.h:454
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:975
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:399
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
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:276
vnet_sub_interface_t sub
Definition: interface.h:596
void ip4_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip4_forward.c:860
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:946
#define VNET_HW_INTERFACE_FLAG_SPEED_SHIFT
Definition: interface.h:407
Set interface MTU.
Definition: interface.api:26
static void vl_api_sw_interface_set_mac_address_t_handler(vl_api_sw_interface_set_mac_address_t *mp)
Reply to get_sw_interface_vrf.
Definition: interface.api:202
#define REPLY_MACRO(t)
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:652
void ip_del_all_interface_addresses(vlib_main_t *vm, u32 sw_if_index)
Definition: ip46_cli.c:80
Set or delete one or all ip addresses on a specified interface.
Definition: interface.api:157
vnet_hw_interface_class_t ethernet_hw_interface_class
static void setup_message_id_table(api_main_t *am)
static uword vlib_process_get_events_with_type(vlib_main_t *vm, uword **data_vector, uword with_type_opaque)
Definition: node_funcs.h:597
#define BAD_SW_IF_INDEX_LABEL
api_main_t api_main
Definition: api_shared.c:35
static void vl_api_sw_interface_set_flags_t_handler(vl_api_sw_interface_set_flags_t *mp)
Definition: interface_api.c:65
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:44
void stats_dslock_with_hint(int hint, int tag)
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
static clib_error_t * admin_up_down_function(vnet_main_t *vm, u32 hw_if_index, u32 flags)
#define API_ADMIN_UP_DOWN_EVENT
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:69
unix_shared_memory_queue_t * vl_api_client_index_to_input_queue(u32 index)
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:118
#define ARRAY_LEN(x)
Definition: clib.h:59
#define foreach_vpe_api_msg
Definition: interface_api.c:51
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(admin_up_down_function)
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:129
foreach_registration_hash u8 link_state_process_up
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:560
void vl_msg_api_send_shmem(unix_shared_memory_queue_t *q, u8 *elem)
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
ip6_main_t ip6_main
Definition: ip6_forward.c:2926
ip_lookup_main_t lookup_main
Definition: ip6.h:148
static void vnet_set_sw_interface_tag(vnet_main_t *vnm, u8 *tag, u32 sw_if_index)
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
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1041
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)
static void vl_api_sw_interface_clear_stats_t_handler(vl_api_sw_interface_clear_stats_t *mp)
struct vnet_sub_interface_t::@151::@152::@154 flags
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
static void vl_api_sw_interface_set_mtu_t_handler(vl_api_sw_interface_set_mtu_t *mp)
Definition: interface_api.c:89
u64 uword
Definition: types.h:112
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
unsigned short u16
Definition: types.h:57
i64 word
Definition: types.h:111
u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:426
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:673
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:960
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:644
Set unnumbered interface add / del request.
Definition: interface.api:254
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:180
struct vnet_sub_interface_t::@151 eth
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:297
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:43
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
vnet_sw_interface_type_t type
Definition: interface.h:555
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1168
pub_sub_handler(interface_events, INTERFACE_EVENTS)
static void send_sw_interface_flags(vpe_api_main_t *am, unix_shared_memory_queue_t *q, vnet_sw_interface_t *swif)
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:545
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:472
Interface details structure (fix this)
Definition: interface.api:77
static void vl_api_sw_interface_set_table_t_handler(vl_api_sw_interface_set_table_t *mp)
u32 flags
Definition: vhost-user.h:76
Set / clear software interface tag.
Definition: interface.api:282
ethernet_interface_t * interfaces
Definition: ethernet.h:243
Associate the specified interface with a fib table.
Definition: interface.api:176
u32 * fib_index_by_sw_if_index
Definition: ip6.h:163
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip6_forward.c:421
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:29
struct _unix_shared_memory_queue unix_shared_memory_queue_t
u32 ethernet_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:339