106 i32 diff_time = client_state->
T2 - current_time;
109 params.
mrd = diff_time;
119 params.
mrd = diff_time;
129 if (
vec_len (address_list) != 0)
131 for (i = 0; i <
vec_len (address_list); i++)
134 addr = &addresses[
i];
165 vl_api_dhcp6_address_info_t *api_address;
166 u32 inner_status_code;
200 (
"Advertise message arrived with NoAddrsAvail status code");
206 for (i = 0; i < n_addresses; i++)
211 address_info = &address_list[i];
212 address_info->
address = *address;
213 address_info->preferred_lt = 0;
214 address_info->valid_lt = 0;
229 clib_warning (
"Reply message arrived with Server ID different " 230 "from that in Request or Renew message");
236 clib_warning (
"Reply message arrived with NoAddrsAvail status code");
240 (
"Invalid Reply message arrived: It contains NoAddrsAvail " 241 "status code but also contains addresses");
248 clib_warning (
"Reply message arrived with UnspecFail status code");
255 for (i = 0; i < n_addresses; i++)
268 valid_time = ntohl (api_address->valid_time);
269 preferred_time = ntohl (api_address->preferred_time);
271 if (preferred_time > valid_time)
274 u8 address_already_present = 0;
278 if (address_info->sw_if_index != sw_if_index)
280 else if (!ip6_addresses_equal (&address_info->address, address))
284 address_already_present = 1;
285 goto address_pool_foreach_out;
289 address_pool_foreach_out:
291 if (address_already_present)
295 address_info->due_time = current_time;
310 address_info->address = *
address;
313 address_info->due_time = current_time;
323 &address_info->address, 64, 0);
328 client_state->server_index = server_index;
329 client_state->T1 = ntohl (mp->T1);
330 client_state->T2 = ntohl (mp->T2);
331 if (client_state->T1 != 0)
332 client_state->T1_due_time = current_time + client_state->T1;
333 if (client_state->T2 != 0)
334 client_state->T2_due_time = current_time + client_state->T2;
335 client_state->rebinding = 0;
351 if (address_info->sw_if_index == sw_if_index)
353 u32 pos = vec_len (address_list);
354 vec_validate (address_list, pos);
355 clib_memcpy (&address_list[pos], address_info, sizeof (*address_info));
372 f64 sleep_time = 1e9;
377 uword *event_data = 0;
396 due_time = current_time + 1e9;
400 if (address_info->due_time > current_time)
402 if (address_info->due_time < due_time)
403 due_time = address_info->due_time;
407 u32 sw_if_index = address_info->sw_if_index;
408 error = ip6_add_del_interface_address (vm, sw_if_index,
409 &address_info->address,
412 clib_warning (
"Failed to delete interface address");
413 pool_put (rm->address_pool, address_info);
415 ip6_link_enable (sw_if_index);
416 client_state = &rm->client_state_by_sw_if_index[sw_if_index];
417 if (--client_state->address_count == 0)
419 client_state->rebinding = 0;
420 client_state->server_index = ~0;
421 send_client_message_start_stop (sw_if_index, ~0,
469 while (due_time < current_time);
471 sleep_time = due_time - current_time;
481 .name =
"dhcp6-client-cp-process",
531 vlib_cli_output (vm,
"address: %U, " 532 "preferred lifetime: %u, valid lifetime: %u " 534 format_ip6_address, &address_info->address,
535 address_info->preferred_lt, address_info->valid_lt,
536 address_info->due_time - current_time);
545 .path =
"show dhcp6 addresses",
546 .short_help =
"show dhcp6 addresses",
562 const char *rebinding;
572 sprintf (buf1,
"%u remaining",
576 sprintf (buf1,
"timeout");
578 sprintf (buf2,
"%u remaining",
581 sprintf (buf2,
"timeout");
583 rebinding =
", REBINDING";
588 "sw_if_index: %u, T1: %u (%s), " 589 "T2: %u (%s), server index: %d%s", i,
590 cs->
T1, buf1, cs->
T2, buf2,
602 .path =
"show dhcp6 clients",
603 .short_help =
"show dhcp6 clients",
634 if (!old_enabled && enable)
647 else if (old_enabled && !enable)
661 if (address_info->sw_if_index == sw_if_index)
663 ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
664 rm->client_state_by_sw_if_index[sw_if_index].enabled);
665 client_state_t *client_state =
666 &rm->client_state_by_sw_if_index[sw_if_index];
667 send_client_message_start_stop (sw_if_index,
668 client_state->server_index,
669 DHCPV6_MSG_RELEASE, address_info,
671 error = ip6_add_del_interface_address (vm, sw_if_index,
672 &address_info->address,
675 clib_warning (
"Failed to delete interface address");
676 pool_put (rm->address_pool, address_info);
683 client_state->enabled = 0;
708 else if (
unformat (line_input,
"disable"))
720 if (sw_if_index != ~0)
746 .path =
"dhcp6 client",
747 .short_help =
"dhcp6 client <interface> [disable]",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static u8 ip6_addresses_equal(ip6_address_t *address1, ip6_address_t *address2)
VNET_DHCP6_REPLY_EVENT_FUNCTION(dhcp6_reply_event_handler)
static address_info_t * create_address_list(u32 sw_if_index)
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...
static clib_error_t * dhcp_ia_na_client_cp_init(vlib_main_t *vm)
vnet_main_t * vnet_get_main(void)
int dhcp6_client_enable_disable(u32 sw_if_index, u8 enable)
static f64 vlib_time_now(vlib_main_t *vm)
static void enable_process(void)
unformat_function_t unformat_vnet_sw_interface
static clib_error_t * dhcp6_client_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
address_info_t * address_pool
static dhcp6_client_cp_main_t dhcp6_client_cp_main
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vl_api_interface_index_t sw_if_index
#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 clib_error_t * dhcp6_reply_event_handler(vl_api_dhcp6_reply_event_t *mp)
#define clib_error_return(e, args...)
vl_api_dhcp6_address_info_t addresses[n_addresses]
static void interrupt_process(void)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
int ip6_link_enable(u32 sw_if_index)
IPv6 Configuration on an interface.
static clib_error_t * dhcp6_clients_show_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
API main structure, used by both vpp and binary API clients.
#define VLIB_REGISTER_NODE(x,...)
dhcp6_send_client_message_params_address_t * addresses
#define vec_free(V)
Free vector's memory (no header).
static void disable_process(void)
#define clib_warning(format, args...)
vlib_main_t vlib_node_runtime_t * node
#define VLIB_CLI_COMMAND(x,...)
manual_print typedef address
vl_api_dhcpv6_msg_type_t msg_type
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
void dhcp6_send_client_message(vlib_main_t *vm, u32 sw_if_index, u8 stop, dhcp6_send_client_message_params_t *params)
static clib_error_t * dhcp6_addresses_show_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_elt(v, i)
Get vector value at index i.
Tell client about a DHCPv6 server reply event.
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
static void send_client_message_start_stop(u32 sw_if_index, u32 server_index, u8 msg_type, address_info_t *address_list, u8 start)
static uword dhcp6_client_cp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_node_main_t node_main
void dhcp6_clients_enable_disable(u8 enable)
static api_main_t * vlibapi_get_main(void)
vlib_node_registration_t dhcp6_client_cp_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_client_cp_process_node)
vl_api_interface_index_t sw_if_index
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)
void vlib_start_process(vlib_main_t *vm, uword process_index)
client_state_t * client_state_by_sw_if_index
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)