36 #define foreach_rd_cp_msg \ 37 _(IP6_ND_ADDRESS_AUTOCONFIG, ip6_nd_address_autoconfig) 91 #define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler 153 ip46_address_t nh = {
193 ip46_address_t nh = {
255 return prefix1->
as_u64[1] >> (128 -
len) ==
256 prefix2->
as_u64[1] >> (128 - len);
258 return prefix1->
as_u64[0] >> (64 -
len) == prefix2->
as_u64[0] >> (64 - len);
261 #define PREFIX_FLAG_A (1 << 6) 262 #define PREFIX_FLAG_L (1 << 7) 275 u16 router_lifetime_in_sec;
293 u8 route_already_present = 0;
297 if (default_route->sw_if_index != sw_if_index)
299 else if (0 != memcmp (&default_route->router_address,
300 &r->router_address, 16))
304 route_already_present = 1;
305 goto default_route_pool_foreach_out;
309 default_route_pool_foreach_out:
311 if (!route_already_present)
313 if (router_lifetime_in_sec != 0)
315 current_time + router_lifetime_in_sec);
319 if (router_lifetime_in_sec != 0)
320 default_route->
due_time = current_time + router_lifetime_in_sec;
332 if (!if_config->enabled)
335 n_prefixes =
vec_len (r->prefixes);
336 for (
i = 0;
i < n_prefixes;
i++)
349 dst_address = &
prefix->prefix.fp_addr.ip6;
350 prefix_length =
prefix->prefix.fp_len;
355 valid_time =
prefix->valid_time;
356 preferred_time =
prefix->preferred_time;
358 if (preferred_time > valid_time)
361 if (prefix_length != 64)
364 u8 address_already_present = 0;
368 if (slaac_address->sw_if_index != sw_if_index)
370 else if (slaac_address->address_length != prefix_length)
372 else if (!ip6_prefixes_equal (&slaac_address->address, dst_address,
377 address_already_present = 1;
378 goto slaac_address_pool_foreach_out;
382 slaac_address_pool_foreach_out:
384 if (address_already_present)
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;
397 due_time = current_time + valid_time;
400 addr.
as_u64[0] = dst_address->as_u64[0];
405 addr.
as_u8[11] = 0xFF;
406 addr.
as_u8[12] = 0xFE;
424 uword *event_data = 0;
428 f64 sleep_time = 1e9;
442 due_time = current_time + 1e9;
446 if (slaac_address->due_time > current_time)
448 if (slaac_address->due_time < due_time)
449 due_time = slaac_address->due_time;
453 remove_slaac_address (vm, slaac_address);
455 ip6_enable (slaac_address->sw_if_index);
460 if (default_route->due_time > current_time)
462 if (default_route->due_time < due_time)
463 due_time = default_route->due_time;
471 while (due_time < current_time);
473 sleep_time = due_time - current_time;
483 .name =
"rd-cp-process",
509 install_default_routes = 0;
528 if (!if_config->
enabled && enable)
531 if ((!if_config->
enabled && enable)
534 else if (if_config->
enabled && !enable)
537 if (if_config->
enabled && !enable)
542 remove_slaac_address (vm, slaac_address);
551 remove_default_route (vm, default_route);
571 u8 default_route = 0;
578 if (
unformat (input,
"default-route"))
586 if (sw_if_index != ~0)
614 .path =
"ip6 nd address autoconfig",
615 .short_help =
"ip6 nd address autoconfig <interface> [default-route|disable]",
624 vl_api_ip6_nd_address_autoconfig_reply_t *rmp;
641 #define vl_msg_name_crc_list 642 #include <vnet/ip/rd_cp.api.h> 643 #undef vl_msg_name_crc_list 648 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); 649 foreach_vl_msg_name_crc_rd_cp;
667 vl_msg_api_set_handlers(VL_API_##N, #n, \ 668 vl_api_##n##_t_handler, \ 670 vl_api_##n##_t_endian, \ 671 vl_api_##n##_t_print, \ 672 sizeof(vl_api_##n##_t), 0); vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
fib_protocol_t fp_proto
protocol type
VNET_IP6_NEIGHBOR_RA_FUNCTION(ip6_ra_report_handler)
#define vlib_log_warn(...)
static u8 ip6_prefixes_equal(ip6_address_t *prefix1, ip6_address_t *prefix2, u8 len)
static int add_slaac_address(vlib_main_t *vm, u32 sw_if_index, u8 address_length, ip6_address_t *address, f64 due_time)
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...
vnet_main_t * vnet_get_main(void)
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, icmp6_send_router_solicitation_params_t *params)
#define clib_memcpy_fast(a, b, c)
slaac_address_t * slaac_address_pool
static f64 vlib_time_now(vlib_main_t *vm)
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.
static clib_error_t * ip6_ra_report_handler(void *data)
static void vl_api_ip6_nd_address_autoconfig_t_handler(vl_api_ip6_nd_address_autoconfig_t *mp)
#define foreach_rd_cp_msg
u8 install_default_routes
unformat_function_t unformat_vnet_sw_interface
ip6_address_t router_address
static u32 ip6_enable(u32 sw_if_index)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static clib_error_t * rd_cp_init(vlib_main_t *vm)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void setup_message_id_table(api_main_t *am)
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.
ethernet_main_t ethernet_main
svm_queue_t * vl_input_queue
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
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...
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Aggregrate type for a prefix.
#define clib_error_return(e, args...)
Enable/disable IPv6 ND address autoconfiguration and setting up default routes.
ip6_address_t router_address
static void remove_default_route(vlib_main_t *vm, default_route_t *default_route)
static uword rd_cp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
#define pool_put(P, E)
Free an object E in pool P.
static void add_default_route(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *next_hop_address, f64 due_time)
u16 router_lifetime_in_sec
API main structure, used by both vpp and binary API clients.
vlib_log_class_t log_class
u8 install_default_routes
#define BAD_SW_IF_INDEX_LABEL
#define VLIB_REGISTER_NODE(x,...)
vlib_node_registration_t rd_cp_process_node
(constructor) VLIB_REGISTER_NODE (rd_cp_process_node)
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
#define VLIB_CLI_COMMAND(x,...)
interface_config_t * config_by_sw_if_index
default_route_t * default_route_pool
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
From the control plane API.
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.
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)
static int remove_slaac_address(vlib_main_t *vm, slaac_address_t *slaac_address)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void interrupt_process(void)
static void router_solicitation_start_stop(u32 sw_if_index, u8 start)
struct _svm_queue svm_queue_t
vnet_sw_interface_type_t type
static u32 get_interface_mac_address(u32 sw_if_index, u8 mac[])
static int set_address_autoconfig(u32 sw_if_index, u8 enable, u8 install_default_routes)
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)
#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)
static clib_error_t * ip6_nd_address_autoconfig(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VALIDATE_SW_IF_INDEX(mp)