FD.io VPP  v19.08.1-401-g8e4ed521a
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
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
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_fast (mac, eth_if->address, 6);
231 
232  return 0;
233 }
234 
235 static u32
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;
275  u16 router_lifetime_in_sec;
276  u32 n_prefixes;
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, &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 
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->prefix.fp_addr.ip6;
350  prefix_length = prefix->prefix.fp_len;
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  u32 index;
444  /*
445  * we do not use pool_foreach() to iterate over pool elements here
446  * as we are removing elements inside the loop body
447  */
448  /* *INDENT-OFF* */
450  ({
451  slaac_address = pool_elt_at_index(rm->slaac_address_pool, index);
452  if (slaac_address->due_time > current_time)
453  {
454  if (slaac_address->due_time < due_time)
455  due_time = slaac_address->due_time;
456  }
457  else
458  {
459  u32 sw_if_index = slaac_address->sw_if_index;
460  remove_slaac_address (vm, slaac_address);
461  /* make sure ip6 stays enabled */
462  ip6_enable (sw_if_index);
463  }
464  }));
466  ({
467  default_route = pool_elt_at_index(rm->default_route_pool, index);
468  if (default_route->due_time > current_time)
469  {
470  if (default_route->due_time < due_time)
471  due_time = default_route->due_time;
472  }
473  else
474  remove_default_route (vm, default_route);
475  }));
476  /* *INDENT-ON* */
477  current_time = vlib_time_now (vm);
478  }
479  while (due_time < current_time);
480 
481  sleep_time = due_time - current_time;
482  }
483 
484  return 0;
485 }
486 
487 /* *INDENT-OFF* */
489  .function = rd_cp_process,
490  .type = VLIB_NODE_TYPE_PROCESS,
491  .name = "rd-cp-process",
492 };
493 /* *INDENT-ON* */
494 
495 static void
497 {
498  rd_cp_main_t *rm = &rd_cp_main;
499  vlib_main_t *vm = rm->vlib_main;
500 
503 }
504 
505 static int
506 set_address_autoconfig (u32 sw_if_index, u8 enable, u8 install_default_routes)
507 {
508  rd_cp_main_t *rm = &rd_cp_main;
509  vlib_main_t *vm = rm->vlib_main;
510  vnet_main_t *vnm = rm->vnet_main;
511  interface_config_t *if_config;
512  interface_config_t empty_config = { 0, 0 };
513  slaac_address_t *slaac_address;
514  default_route_t *default_route;
515 
516  if (!enable)
517  install_default_routes = 0;
518 
519  if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
520  {
521  vlib_log_warn (rm->log_class, "Invalid sw_if_index");
522  return 1;
523  }
524 
525  if (!rm->enabled)
526  {
527  /* process kickoff */
529  rm->enabled = 1;
530  }
531 
533  empty_config);
534  if_config = &rm->config_by_sw_if_index[sw_if_index];
535 
536  if (!if_config->enabled && enable)
537  ip6_enable (sw_if_index);
538 
539  if ((!if_config->enabled && enable)
540  || (!if_config->install_default_routes && install_default_routes))
541  router_solicitation_start_stop (sw_if_index, 1);
542  else if (if_config->enabled && !enable)
543  router_solicitation_start_stop (sw_if_index, 0);
544 
545  if (if_config->enabled && !enable)
546  {
547  /* *INDENT-OFF* */
548  pool_foreach (slaac_address, rm->slaac_address_pool,
549  ({
550  remove_slaac_address (vm, slaac_address);
551  }));
552  /* *INDENT-ON* */
553  }
554  if (if_config->install_default_routes && !install_default_routes)
555  {
556  /* *INDENT-OFF* */
557  pool_foreach (default_route, rm->default_route_pool,
558  ({
559  remove_default_route (vm, default_route);
560  }));
561  /* *INDENT-ON* */
562  }
563 
564  if_config->enabled = enable;
565  if_config->install_default_routes = install_default_routes;
566 
567  return 0;
568 }
569 
570 static clib_error_t *
572  unformat_input_t * input, vlib_cli_command_t * cmd)
573 {
574  rd_cp_main_t *rm = &rd_cp_main;
575  vnet_main_t *vnm = rm->vnet_main;
576  clib_error_t *error = 0;
577  u32 sw_if_index = ~0;
578  u8 enable = 1;
579  u8 default_route = 0;
580 
582  {
583  if (unformat
584  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
585  ;
586  if (unformat (input, "default-route"))
587  default_route = 1;
588  if (unformat (input, "disable"))
589  enable = 0;
590  else
591  break;
592  }
593 
594  if (sw_if_index != ~0)
595  {
596  if (set_address_autoconfig (sw_if_index, enable, default_route) != 0)
597  error = clib_error_return (0, "Invalid sw_if_index");
598  }
599  else
600  error = clib_error_return (0, "Missing sw_if_index");
601 
602  return error;
603 }
604 
605 /*?
606  * This command is used to enable ND address autoconfiguration
607  * on particular interface including setting up default routes.
608  *
609  * @cliexpar
610  * @parblock
611  * Example of how to enable ND address autoconfiguration:
612  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0}
613  * Example of how to enable ND address autoconfiguration
614  * with setting up default routes:
615  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 default-route}
616  * Example of how to disable ND address autoconfiguration:
617  * @cliexcmd{ip6 nd address autoconfig GigabitEthernet2/0/0 disable}
618  * @endparblock
619 ?*/
620 /* *INDENT-OFF* */
621 VLIB_CLI_COMMAND (ip6_nd_address_autoconfig_command, static) = {
622  .path = "ip6 nd address autoconfig",
623  .short_help = "ip6 nd address autoconfig <interface> [default-route|disable]",
624  .function = ip6_nd_address_autoconfig,
625 };
626 /* *INDENT-ON* */
627 
628 static void
630  * mp)
631 {
632  vl_api_ip6_nd_address_autoconfig_reply_t *rmp;
634  int rv = 0;
635 
637 
638  sw_if_index = ntohl (mp->sw_if_index);
639 
640  rv =
641  set_address_autoconfig (sw_if_index, mp->enable,
643 
645 
646  REPLY_MACRO (VL_API_IP6_ND_ADDRESS_AUTOCONFIG_REPLY);
647 }
648 
649 #define vl_msg_name_crc_list
650 #include <vnet/ip/rd_cp.api.h>
651 #undef vl_msg_name_crc_list
652 
653 static void
655 {
656 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
657  foreach_vl_msg_name_crc_rd_cp;
658 #undef _
659 }
660 
661 static clib_error_t *
663 {
664  rd_cp_main_t *rm = &rd_cp_main;
665  api_main_t *am = &api_main;
666 
667  rm->vlib_main = vm;
668  rm->vnet_main = vnet_get_main ();
669  rm->api_main = am;
670  rm->node_index = rd_cp_process_node.index;
671 
672  rm->log_class = vlib_log_register_class ("rd_cp", 0);
673 
674 #define _(N,n) \
675  vl_msg_api_set_handlers(VL_API_##N, #n, \
676  vl_api_##n##_t_handler, \
677  vl_noop_handler, \
678  vl_api_##n##_t_endian, \
679  vl_api_##n##_t_print, \
680  sizeof(vl_api_##n##_t), 0/* do NOT trace! */);
682 #undef _
683 
684  /*
685  * Set up the (msg_name, crc, message-id) table
686  */
688 
689  return 0;
690 }
691 
693 
694 /*
695  * fd.io coding-style-patch-verification: ON
696  *
697  * Local Variables:
698  * eval: (c-set-style "gnu")
699  * End:
700  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:176
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
#define PREFIX_FLAG_A
Definition: rd_cp.c:261
typedef address
Definition: ip_types.api:83
VNET_IP6_NEIGHBOR_RA_FUNCTION(ip6_ra_report_handler)
#define vlib_log_warn(...)
Definition: log.h:103
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:673
vl_api_mac_address_t mac
Definition: l2.api:490
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
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 clib_memcpy_fast(a, b, c)
Definition: string.h:81
#define NULL
Definition: clib.h:58
slaac_address_t * slaac_address_pool
Definition: rd_cp.c:66
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:279
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:972
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:629
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
u8 data[128]
Definition: ipsec.api:251
ip6_address_t router_address
Definition: rd_cp.c:50
static u32 ip6_enable(u32 sw_if_index)
Definition: rd_cp.c:236
vl_api_mprefix_t prefix
Definition: ip.api:456
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
static clib_error_t * rd_cp_init(vlib_main_t *vm)
Definition: rd_cp.c:662
#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:654
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:788
ethernet_main_t ethernet_main
Definition: init.c:45
u32 vlib_log_class_t
Definition: vlib.h:51
svm_queue_t * vl_input_queue
Definition: rd_cp.c:71
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:516
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Aggregate type for a prefix.
Definition: fib_types.h:203
#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
ip6_address_t router_address
Definition: ip6_neighbor.h:124
Definition: fib_entry.h:281
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:934
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:286
#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:127
u8 address_length
Definition: rd_cp.c:42
u8 len
Definition: ip_types.api:90
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:203
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:169
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
vlib_main_t * vm
Definition: buffer.c:323
u8 enabled
Definition: rd_cp.c:62
vlib_node_registration_t rd_cp_process_node
(constructor) VLIB_REGISTER_NODE (rd_cp_process_node)
Definition: rd_cp.c:488
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:161
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:326
From the control plane API.
Definition: fib_entry.h:79
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:705
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:886
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:496
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:701
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:506
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:289
f64 due_time
Definition: rd_cp.c:44
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:538
#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:571
api_main_t api_main
Definition: api_shared.c:35
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
#define VALIDATE_SW_IF_INDEX(mp)