FD.io VPP  v18.07-rc0-415-g6c78436
Vector Packet Processing
rd_cp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vnet/vnet.h>
17 #include <vlibmemory/api.h>
18 #include <vnet/vnet_msg_enum.h>
19 #include <vnet/ip/ip6.h>
20 #include <vnet/ethernet/ethernet.h>
21 #include <vnet/ip/ip6_neighbor.h>
22 #include <vnet/fib/fib_table.h>
23 #include <signal.h>
24 #include <math.h>
25 
26 #define vl_typedefs /* define message structures */
27 #include <vnet/vnet_all_api_h.h>
28 #undef vl_typedefs
29 
30 #define vl_endianfun /* define message structures */
31 #include <vnet/vnet_all_api_h.h>
32 #undef vl_endianfun
33 
35 
36 #define foreach_rd_cp_msg \
37 _(IP6_ND_ADDRESS_AUTOCONFIG, ip6_nd_address_autoconfig)
38 
39 typedef struct
40 {
46 
47 typedef struct
48 {
53 
54 typedef struct
55 {
59 
60 typedef struct
61 {
64 
68 
69  /* binary API client */
73 
74  /* logging */
76 
77  /* convenience */
82 } rd_cp_main_t;
83 
85 
86 enum
87 {
89 };
90 
91 #define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler
92 
93 static void
95 {
96  rd_cp_main_t *rm = &rd_cp_main;
98 
99  if (start)
100  {
101  params.irt = 1;
102  params.mrt = 120;
103  }
104 
105  icmp6_send_router_solicitation (rm->vlib_main, sw_if_index, !start,
106  &params);
107 }
108 
109 static void interrupt_process (void);
110 
111 static int
112 add_slaac_address (vlib_main_t * vm, u32 sw_if_index, u8 address_length,
113  ip6_address_t * address, f64 due_time)
114 {
115  rd_cp_main_t *rm = &rd_cp_main;
116  slaac_address_t *slaac_address;
117  clib_error_t *rv = 0;
118 
119  pool_get (rm->slaac_address_pool, slaac_address);
120 
121  slaac_address->sw_if_index = sw_if_index;
122  slaac_address->address_length = address_length;
123  slaac_address->address = *address;
124  slaac_address->due_time = due_time;
125 
126  rv =
127  ip6_add_del_interface_address (vm, sw_if_index, &slaac_address->address,
128  address_length, 0);
129 
130  return rv != 0;
131 }
132 
133 static void
135  ip6_address_t * next_hop_address, f64 due_time)
136 {
137  rd_cp_main_t *rm = &rd_cp_main;
138  default_route_t *default_route;
139 
140  pool_get (rm->default_route_pool, default_route);
141 
142  default_route->sw_if_index = sw_if_index;
143  default_route->router_address = *next_hop_address;
144  default_route->due_time = due_time;
145 
146  {
148  default_route->
149  sw_if_index);
150  fib_prefix_t pfx = {
152  };
153  ip46_address_t nh = {
154  .ip6 = default_route->router_address,
155  };
156  fib_table_entry_update_one_path (fib_index, &pfx,
160  &nh,
161  default_route->sw_if_index,
163  }
164 }
165 
166 static int
168 {
169  rd_cp_main_t *rm = &rd_cp_main;
170  clib_error_t *rv = 0;
171 
172  rv = ip6_add_del_interface_address (vm, slaac_address->sw_if_index,
173  &slaac_address->address,
174  slaac_address->address_length, 1);
175 
176  pool_put (rm->slaac_address_pool, slaac_address);
177 
178  return rv != 0;
179 }
180 
181 static void
183 {
184  rd_cp_main_t *rm = &rd_cp_main;
185 
186  {
188  default_route->
189  sw_if_index);
190  fib_prefix_t pfx = {
192  };
193  ip46_address_t nh = {
194  .ip6 = default_route->router_address,
195  };
196  fib_table_entry_path_remove (fib_index, &pfx,
199  &nh,
200  default_route->sw_if_index,
202  }
203 
204  pool_put (rm->default_route_pool, default_route);
205 }
206 
207 static u32
208 get_interface_mac_address (u32 sw_if_index, u8 mac[])
209 {
210  rd_cp_main_t *rm = &rd_cp_main;
212  ethernet_interface_t *eth_if = 0;
213 
214  if (!vnet_sw_interface_is_api_valid (rm->vnet_main, sw_if_index))
215  {
216  vlib_log_warn (rm->log_class, "Invalid sw_if_index");
217  return 1;
218  }
219 
220  si = vnet_get_sup_sw_interface (rm->vnet_main, sw_if_index);
223 
224  if (!eth_if)
225  {
226  vlib_log_warn (rm->log_class, "Failed to get hardware interface");
227  return 1;
228  }
229 
230  clib_memcpy (mac, eth_if->address, 6);
231 
232  return 0;
233 }
234 
235 static u32
236 ip6_enable (u32 sw_if_index)
237 {
238  rd_cp_main_t *rm = &rd_cp_main;
239  clib_error_t *rv;
240 
241  rv = enable_ip6_interface (rm->vlib_main, sw_if_index);
242 
243  return rv != 0;
244 }
245 
246 static u8
248 {
249  if (len >= 64)
250  {
251  if (prefix1->as_u64[0] != prefix2->as_u64[0])
252  return 0;
253  if (len == 64)
254  return 1;
255  return prefix1->as_u64[1] >> (128 - len) ==
256  prefix2->as_u64[1] >> (128 - len);
257  }
258  return prefix1->as_u64[0] >> (64 - len) == prefix2->as_u64[0] >> (64 - len);
259 }
260 
261 #define PREFIX_FLAG_A (1 << 6)
262 #define PREFIX_FLAG_L (1 << 7)
263 
264 static clib_error_t *
266 {
267  rd_cp_main_t *rm = &rd_cp_main;
268  vlib_main_t *vm = rm->vlib_main;
269  clib_error_t *error = 0;
270  ra_report_t *r = data;
271  interface_config_t *if_config;
272  default_route_t *default_route;
273  slaac_address_t *slaac_address;
274  u32 sw_if_index;
275  u16 router_lifetime_in_sec;
276  u32 n_prefixes;
277  ra_report_prefix_info_t *prefix;
278  u8 mac[6];
279  f64 current_time;
280  u32 i;
281 
282  current_time = vlib_time_now (vm);
283 
284  sw_if_index = r->sw_if_index;
285 
286  if (sw_if_index >= vec_len (rm->config_by_sw_if_index))
287  return 0;
288  if_config = &rm->config_by_sw_if_index[sw_if_index];
289 
290  if (if_config->install_default_routes)
291  {
292  router_lifetime_in_sec = r->router_lifetime_in_sec;
293  u8 route_already_present = 0;
294  /* *INDENT-OFF* */
295  pool_foreach (default_route, rm->default_route_pool,
296  ({
297  if (default_route->sw_if_index != sw_if_index)
298  ;
299  else if (0 != memcmp (&default_route->router_address,
300  r->router_address, 16))
301  ;
302  else
303  {
304  route_already_present = 1;
305  goto default_route_pool_foreach_out;
306  }
307  }));
308  /* *INDENT-ON* */
309  default_route_pool_foreach_out:
310 
311  if (!route_already_present)
312  {
313  if (router_lifetime_in_sec != 0)
314  add_default_route (vm, sw_if_index, (void *) r->router_address,
315  current_time + router_lifetime_in_sec);
316  }
317  else
318  {
319  if (router_lifetime_in_sec != 0)
320  default_route->due_time = current_time + router_lifetime_in_sec;
321  else
322  remove_default_route (vm, default_route);
323  }
324  }
325 
326  if (get_interface_mac_address (sw_if_index, mac) != 0)
327  {
328  vlib_log_warn (rm->log_class, "Error getting MAC address");
329  return clib_error_return (0, "Error getting MAC address");
330  }
331 
332  if (!if_config->enabled)
333  return 0;
334 
335  n_prefixes = vec_len (r->prefixes);
336  for (i = 0; i < n_prefixes; i++)
337  {
338  ip6_address_t *dst_address;
339  u8 prefix_length;
340  u32 valid_time;
341  u32 preferred_time;
342  f64 due_time;
343 
344  prefix = &r->prefixes[i];
345 
346  if (!(prefix->flags & PREFIX_FLAG_A))
347  continue;
348 
349  dst_address = &prefix->dst_address;
350  prefix_length = prefix->dst_address_length;
351 
352  if (ip6_address_is_link_local_unicast (dst_address))
353  continue;
354 
355  valid_time = prefix->valid_time;
356  preferred_time = prefix->preferred_time;
357 
358  if (preferred_time > valid_time)
359  continue;
360 
361  if (prefix_length != 64)
362  continue;
363 
364  u8 address_already_present = 0;
365  /* *INDENT-OFF* */
366  pool_foreach (slaac_address, rm->slaac_address_pool,
367  ({
368  if (slaac_address->sw_if_index != sw_if_index)
369  ;
370  else if (slaac_address->address_length != prefix_length)
371  ;
372  else if (!ip6_prefixes_equal (&slaac_address->address, dst_address,
373  prefix_length))
374  ;
375  else
376  {
377  address_already_present = 1;
378  goto slaac_address_pool_foreach_out;
379  }
380  }));
381  /* *INDENT-ON* */
382  slaac_address_pool_foreach_out:
383 
384  if (address_already_present)
385  {
386  f64 remaining_life_time = slaac_address->due_time - current_time;
387  if (valid_time > 2 * 60 * 60 || valid_time > remaining_life_time)
388  slaac_address->due_time = current_time + valid_time;
389  else if (remaining_life_time > 2 * 60 * 60)
390  slaac_address->due_time = current_time + 2 * 60 * 60;
391  continue;
392  }
393 
394  if (valid_time == 0)
395  continue;
396 
397  due_time = current_time + valid_time;
398 
400  addr.as_u64[0] = dst_address->as_u64[0];
401  /* Invert the "u" bit */
402  addr.as_u8[8] = mac[0] ^ (1 << 1);
403  addr.as_u8[9] = mac[1];
404  addr.as_u8[10] = mac[2];
405  addr.as_u8[11] = 0xFF;
406  addr.as_u8[12] = 0xFE;
407  addr.as_u8[13] = mac[3];
408  addr.as_u8[14] = mac[4];
409  addr.as_u8[15] = mac[5];
410 
411  add_slaac_address (vm, sw_if_index, prefix_length, &addr, due_time);
412  }
413 
415 
416  return error;
417 }
418 
420 
421 static uword
423 {
424  uword *event_data = 0;
425  rd_cp_main_t *rm = &rd_cp_main;
426  slaac_address_t *slaac_address;
427  default_route_t *default_route;
428  f64 sleep_time = 1e9;
429  f64 current_time;
430  f64 due_time;
431 
432  while (1)
433  {
434  vlib_process_wait_for_event_or_clock (vm, sleep_time);
435  vlib_process_get_events (vm, &event_data);
436 
437  vec_reset_length (event_data);
438 
439  current_time = vlib_time_now (vm);
440  do
441  {
442  due_time = current_time + 1e9;
443  /* *INDENT-OFF* */
444  pool_foreach (slaac_address, rm->slaac_address_pool,
445  ({
446  if (slaac_address->due_time > current_time)
447  {
448  if (slaac_address->due_time < due_time)
449  due_time = slaac_address->due_time;
450  }
451  else
452  {
453  remove_slaac_address (vm, slaac_address);
454  /* make sure ip6 stays enabled */
455  ip6_enable (slaac_address->sw_if_index);
456  }
457  }));
458  pool_foreach (default_route, rm->default_route_pool,
459  ({
460  if (default_route->due_time > current_time)
461  {
462  if (default_route->due_time < due_time)
463  due_time = default_route->due_time;
464  }
465  else
466  remove_default_route (vm, default_route);
467  }));
468  /* *INDENT-ON* */
469  current_time = vlib_time_now (vm);
470  }
471  while (due_time < current_time);
472 
473  sleep_time = due_time - current_time;
474  }
475 
476  return 0;
477 }
478 
479 /* *INDENT-OFF* */
481  .function = rd_cp_process,
482  .type = VLIB_NODE_TYPE_PROCESS,
483  .name = "rd-cp-process",
484 };
485 /* *INDENT-ON* */
486 
487 static void
489 {
490  rd_cp_main_t *rm = &rd_cp_main;
491  vlib_main_t *vm = rm->vlib_main;
492 
495 }
496 
497 static int
498 set_address_autoconfig (u32 sw_if_index, u8 enable, u8 install_default_routes)
499 {
500  rd_cp_main_t *rm = &rd_cp_main;
501  vlib_main_t *vm = rm->vlib_main;
502  vnet_main_t *vnm = rm->vnet_main;
503  interface_config_t *if_config;
504  interface_config_t empty_config = { 0, 0 };
505  slaac_address_t *slaac_address;
506  default_route_t *default_route;
507 
508  if (!enable)
509  install_default_routes = 0;
510 
511  if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
512  {
513  vlib_log_warn (rm->log_class, "Invalid sw_if_index");
514  return 1;
515  }
516 
517  if (!rm->enabled)
518  {
519  /* process kickoff */
521  rm->enabled = 1;
522  }
523 
525  empty_config);
526  if_config = &rm->config_by_sw_if_index[sw_if_index];
527 
528  if (!if_config->enabled && enable)
529  ip6_enable (sw_if_index);
530 
531  if ((!if_config->enabled && enable)
532  || (!if_config->install_default_routes && install_default_routes))
533  router_solicitation_start_stop (sw_if_index, 1);
534  else if (if_config->enabled && !enable)
535  router_solicitation_start_stop (sw_if_index, 0);
536 
537  if (if_config->enabled && !enable)
538  {
539  /* *INDENT-OFF* */
540  pool_foreach (slaac_address, rm->slaac_address_pool,
541  ({
542  remove_slaac_address (vm, slaac_address);
543  }));
544  /* *INDENT-ON* */
545  }
546  if (if_config->install_default_routes && !install_default_routes)
547  {
548  /* *INDENT-OFF* */
549  pool_foreach (default_route, rm->default_route_pool,
550  ({
551  remove_default_route (vm, default_route);
552  }));
553  /* *INDENT-ON* */
554  }
555 
556  if_config->enabled = enable;
557  if_config->install_default_routes = install_default_routes;
558 
559  return 0;
560 }
561 
562 static clib_error_t *
564  unformat_input_t * input, vlib_cli_command_t * cmd)
565 {
566  rd_cp_main_t *rm = &rd_cp_main;
567  vnet_main_t *vnm = rm->vnet_main;
568  clib_error_t *error = 0;
569  u32 sw_if_index = ~0;
570  u8 enable = 1;
571  u8 default_route = 0;
572 
574  {
575  if (unformat
576  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
577  ;
578  if (unformat (input, "default-route"))
579  default_route = 1;
580  if (unformat (input, "disable"))
581  enable = 0;
582  else
583  break;
584  }
585 
586  if (sw_if_index != ~0)
587  {
588  if (set_address_autoconfig (sw_if_index, enable, default_route) != 0)
589  error = clib_error_return (0, "Invalid sw_if_index");
590  }
591  else
592  error = clib_error_return (0, "Missing sw_if_index");
593 
594  return error;
595 }
596 
597 /*?
598  * This command is used to enable ND address autoconfiguration
599  * on particular interface including setting up default routes.
600  *
601  * @cliexpar
602  * @parblock
603  * Example of how to enable ND address autoconfiguration:
604  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0}
605  * Example of how to enable ND address autoconfiguration
606  * with setting up default routes:
607  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 default-route}
608  * Example of how to disable ND address autoconfiguration:
609  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 disable}
610  * @endparblock
611 ?*/
612 /* *INDENT-OFF* */
613 VLIB_CLI_COMMAND (ip6_nd_address_autoconfig_command, static) = {
614  .path = "ip6 nd address autoconfig",
615  .short_help = "ip6 nd address autoconfig <interface> [default-route|disable]",
616  .function = ip6_nd_address_autoconfig,
617 };
618 /* *INDENT-ON* */
619 
620 static void
622  * mp)
623 {
624  vl_api_ip6_nd_address_autoconfig_reply_t *rmp;
625  u32 sw_if_index;
626  int rv = 0;
627 
629 
630  sw_if_index = ntohl (mp->sw_if_index);
631 
632  rv =
633  set_address_autoconfig (sw_if_index, mp->enable,
635 
637 
638  REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
639 }
640 
641 #define vl_msg_name_crc_list
642 #include <vnet/ip/rd_cp.api.h>
643 #undef vl_msg_name_crc_list
644 
645 static void
647 {
648 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
649  foreach_vl_msg_name_crc_rd_cp;
650 #undef _
651 }
652 
653 static clib_error_t *
655 {
656  rd_cp_main_t *rm = &rd_cp_main;
657  api_main_t *am = &api_main;
658 
659  rm->vlib_main = vm;
660  rm->vnet_main = vnet_get_main ();
661  rm->api_main = am;
662  rm->node_index = rd_cp_process_node.index;
663 
664  rm->log_class = vlib_log_register_class ("rd_cp", 0);
665 
666 #define _(N,n) \
667  vl_msg_api_set_handlers(VL_API_##N, #n, \
668  vl_api_##n##_t_handler, \
669  vl_noop_handler, \
670  vl_api_##n##_t_endian, \
671  vl_api_##n##_t_print, \
672  sizeof(vl_api_##n##_t), 0/* do NOT trace! */);
674 #undef _
675 
676  /*
677  * Set up the (msg_name, crc, message-id) table
678  */
680 
681  return 0;
682 }
683 
685 
686 /*
687  * fd.io coding-style-patch-verification: ON
688  *
689  * Local Variables:
690  * eval: (c-set-style "gnu")
691  * End:
692  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:221
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:197
#define PREFIX_FLAG_A
Definition: rd_cp.c:261
typedef address
Definition: ip_types.api:34
VNET_IP6_NEIGHBOR_RA_FUNCTION(ip6_ra_report_handler)
u32 vlib_log_class_t
Definition: log.h:21
#define vlib_log_warn(...)
Definition: log.h:51
static u8 ip6_prefixes_equal(ip6_address_t *prefix1, ip6_address_t *prefix2, u8 len)
Definition: rd_cp.c:247
static int add_slaac_address(vlib_main_t *vm, u32 sw_if_index, u8 address_length, ip6_address_t *address, f64 due_time)
Definition: rd_cp.c:112
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, icmp6_send_router_solicitation_params_t *params)
u8 as_u8[16]
Definition: ip6_packet.h:48
u64 as_u64[2]
Definition: ip6_packet.h:51
#define NULL
Definition: clib.h:55
slaac_address_t * slaac_address_pool
Definition: rd_cp.c:66
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:225
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
vlib_main_t * vlib_main
Definition: rd_cp.c:78
static clib_error_t * ip6_ra_report_handler(void *data)
Definition: rd_cp.c:265
static void vl_api_ip6_nd_address_autoconfig_t_handler(vl_api_ip6_nd_address_autoconfig_t *mp)
Definition: rd_cp.c:621
ip6_address_t address
Definition: rd_cp.c:43
#define foreach_rd_cp_msg
Definition: rd_cp.c:36
u8 install_default_routes
Definition: rd_cp.c:57
int i
unformat_function_t unformat_vnet_sw_interface
ip6_address_t router_address
Definition: rd_cp.c:50
static u32 ip6_enable(u32 sw_if_index)
Definition: rd_cp.c:236
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
unsigned char u8
Definition: types.h:56
static clib_error_t * rd_cp_init(vlib_main_t *vm)
Definition: rd_cp.c:654
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void setup_message_id_table(api_main_t *am)
Definition: rd_cp.c:646
double f64
Definition: types.h:142
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
Definition: fib_table.c:772
ethernet_main_t ethernet_main
Definition: init.c:45
svm_queue_t * vl_input_queue
Definition: rd_cp.c:71
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:542
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Aggregrate type for a prefix.
Definition: fib_types.h:188
#define clib_error_return(e, args...)
Definition: error.h:99
Enable/disable IPv6 ND address autoconfiguration and setting up default routes.
Definition: rd_cp.api:29
unsigned int u32
Definition: types.h:88
vnet_main_t * vnet_main
Definition: rd_cp.c:79
Definition: fib_entry.h:270
static void remove_default_route(vlib_main_t *vm, default_route_t *default_route)
Definition: rd_cp.c:182
static uword rd_cp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: rd_cp.c:422
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:952
f64 due_time
Definition: rd_cp.c:51
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
api_main_t * api_main
Definition: rd_cp.c:80
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
#define REPLY_MACRO(t)
u8 events_on
Definition: rd_cp.c:63
static void add_default_route(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *next_hop_address, f64 due_time)
Definition: rd_cp.c:134
u16 router_lifetime_in_sec
Definition: ip6_neighbor.h:133
u8 address_length
Definition: rd_cp.c:42
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
vlib_log_class_t log_class
Definition: rd_cp.c:75
#define BAD_SW_IF_INDEX_LABEL
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u8 router_address[16]
Definition: ip6_neighbor.h:130
vlib_main_t * vm
Definition: buffer.c:294
u8 enabled
Definition: rd_cp.c:62
#define clib_memcpy(a, b, c)
Definition: string.h:75
vlib_node_registration_t rd_cp_process_node
(constructor) VLIB_REGISTER_NODE (rd_cp_process_node)
Definition: rd_cp.c:480
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
interface_config_t * config_by_sw_if_index
Definition: rd_cp.c:65
rd_cp_main_t rd_cp_main
Definition: rd_cp.c:84
u32 my_client_index
Definition: rd_cp.c:72
default_route_t * default_route_pool
Definition: rd_cp.c:67
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:302
From the control plane API.
Definition: fib_entry.h:70
void fib_table_entry_path_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_route_path_flags_t path_flags)
remove one path to an entry (aka route) in the FIB.
Definition: fib_table.c:682
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:703
static int remove_slaac_address(vlib_main_t *vm, slaac_address_t *slaac_address)
Definition: rd_cp.c:167
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
static void interrupt_process(void)
Definition: rd_cp.c:488
static void router_solicitation_start_stop(u32 sw_if_index, u8 start)
Definition: rd_cp.c:94
struct _svm_queue svm_queue_t
u32 node_index
Definition: rd_cp.c:81
vnet_sw_interface_type_t type
Definition: interface.h:655
static u32 get_interface_mac_address(u32 sw_if_index, u8 mac[])
Definition: rd_cp.c:208
static int set_address_autoconfig(u32 sw_if_index, u8 enable, u8 install_default_routes)
Definition: rd_cp.c:498
u32 sw_if_index
Definition: rd_cp.c:49
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
vhost_vring_addr_t addr
Definition: vhost-user.h:83
f64 due_time
Definition: rd_cp.c:44
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
u32 sw_if_index
Definition: rd_cp.c:41
u8 api_connected
Definition: rd_cp.c:70
static clib_error_t * ip6_nd_address_autoconfig(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: rd_cp.c:563
api_main_t api_main
Definition: api_shared.c:35
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
#define VALIDATE_SW_IF_INDEX(mp)