75 #define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler 119 const ip6_address_t * next_hop_address,
f64 due_time)
137 ip46_address_t
nh = {
177 ip46_address_t
nh = {
224 if (prefix1->as_u64[0] != prefix2->as_u64[0])
228 return prefix1->as_u64[1] >> (128 -
len) ==
229 prefix2->as_u64[1] >> (128 - len);
231 return prefix1->as_u64[0] >> (64 -
len) == prefix2->as_u64[0] >> (64 - len);
234 #define PREFIX_FLAG_A (1 << 6) 235 #define PREFIX_FLAG_L (1 << 7) 246 u16 router_lifetime_in_sec;
264 u8 route_already_present = 0;
268 if (default_route->sw_if_index != sw_if_index)
270 else if (0 != memcmp (&default_route->router_address,
271 &r->router_address, 16))
275 route_already_present = 1;
276 goto default_route_pool_foreach_out;
280 default_route_pool_foreach_out:
282 if (!route_already_present)
284 if (router_lifetime_in_sec != 0)
286 current_time + router_lifetime_in_sec);
290 if (router_lifetime_in_sec != 0)
291 default_route->
due_time = current_time + router_lifetime_in_sec;
303 if (!if_config->enabled)
306 n_prefixes =
vec_len (r->prefixes);
307 for (
i = 0;
i < n_prefixes;
i++)
309 ip6_address_t *dst_address;
320 dst_address = &
prefix->prefix.fp_addr.ip6;
321 prefix_length =
prefix->prefix.fp_len;
326 valid_time =
prefix->valid_time;
327 preferred_time =
prefix->preferred_time;
329 if (preferred_time > valid_time)
332 if (prefix_length != 64)
335 u8 address_already_present = 0;
339 if (slaac_address->sw_if_index != sw_if_index)
341 else if (slaac_address->address_length != prefix_length)
343 else if (!ip6_prefixes_equal (&slaac_address->address, dst_address,
348 address_already_present = 1;
349 goto slaac_address_pool_foreach_out;
353 slaac_address_pool_foreach_out:
355 if (address_already_present)
357 f64 remaining_life_time = slaac_address->due_time - current_time;
359 slaac_address->due_time = current_time +
valid_time;
360 else if (remaining_life_time > 2 * 60 * 60)
361 slaac_address->due_time = current_time + 2 * 60 * 60;
371 addr.as_u64[0] = dst_address->as_u64[0];
373 addr.as_u8[8] =
mac[0] ^ (1 << 1);
376 addr.as_u8[11] = 0xFF;
377 addr.as_u8[12] = 0xFE;
393 uword *event_data = 0;
397 f64 sleep_time = 1e9;
411 due_time = current_time + 1e9;
420 slaac_address = pool_elt_at_index(rm->slaac_address_pool, index);
421 if (slaac_address->due_time > current_time)
423 if (slaac_address->due_time < due_time)
424 due_time = slaac_address->due_time;
428 u32 sw_if_index = slaac_address->sw_if_index;
429 remove_slaac_address (vm, slaac_address);
431 ip6_link_enable (sw_if_index, NULL);
436 default_route = pool_elt_at_index(rm->default_route_pool, index);
437 if (default_route->due_time > current_time)
439 if (default_route->due_time < due_time)
440 due_time = default_route->due_time;
448 while (due_time < current_time);
450 sleep_time = due_time - current_time;
460 .name =
"rd-cp-process",
476 u8 enable,
u8 install_default_routes)
487 install_default_routes = 0;
506 if (!if_config->
enabled && enable)
509 if ((!if_config->
enabled && enable)
512 else if (if_config->
enabled && !enable)
515 if (if_config->
enabled && !enable)
520 remove_slaac_address (vm, slaac_address);
529 remove_default_route (vm, default_route);
549 u8 default_route = 0;
556 if (
unformat (input,
"default-route"))
564 if (sw_if_index != ~0)
593 .path =
"ip6 nd address autoconfig",
594 .short_help =
"ip6 nd address autoconfig <interface> [default-route|disable]",
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
void ip6_ra_report_register(ip6_ra_report_notify_t fn)
fib_protocol_t fp_proto
protocol type
#define vlib_log_warn(...)
static u8 ip6_prefixes_equal(ip6_address_t *prefix1, ip6_address_t *prefix2, u8 len)
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...
int ip6_link_enable(u32 sw_if_index, const ip6_address_t *link_local_addr)
IPv6 Configuration on an interface.
vnet_main_t * vnet_get_main(void)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
#define clib_memcpy_fast(a, b, c)
u16 router_lifetime_in_sec
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 void ip6_ra_report_handler(const ip6_ra_report_t *r)
u8 install_default_routes
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, const icmp6_send_router_solicitation_params_t *params)
unformat_function_t unformat_vnet_sw_interface
ip6_address_t router_address
static clib_error_t * rd_cp_init(vlib_main_t *vm)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
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
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vl_api_interface_index_t sw_if_index
static int add_slaac_address(vlib_main_t *vm, u32 sw_if_index, u8 address_length, const ip6_address_t *address, f64 due_time)
#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)
Aggregate type for a prefix.
#define clib_error_return(e, args...)
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.
vlib_log_class_t log_class
#define VLIB_REGISTER_NODE(x,...)
sll srl srl sll sra u16x4 i
int rd_cp_set_address_autoconfig(u32 sw_if_index, u8 enable, u8 install_default_routes)
vlib_node_registration_t rd_cp_process_node
(constructor) VLIB_REGISTER_NODE (rd_cp_process_node)
#define VLIB_CLI_COMMAND(x,...)
interface_config_t * config_by_sw_if_index
manual_print typedef address
default_route_t * default_route_pool
From the control plane API.
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
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)
vnet_sw_interface_type_t type
static u32 get_interface_mac_address(u32 sw_if_index, u8 mac[])
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 pool_foreach_index(i, v, body)
Iterate pool by index.
#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)
static void add_default_route(vlib_main_t *vm, u32 sw_if_index, const ip6_address_t *next_hop_address, f64 due_time)