36 #define foreach_dhcp6_client_cp_msg \ 37 _(DHCP6_CLIENT_ENABLE_DISABLE, dhcp6_client_enable_disable) 39 #define vl_api_dhcp6_client_enable_disable_t_print vl_noop_handler 120 i32 diff_time = client_state->
T2 - current_time;
123 params.
mrd = diff_time;
133 params.
mrd = diff_time;
143 if (
vec_len (address_list) != 0)
145 for (i = 0; i <
vec_len (address_list); i++)
148 addr = &addresses[
i];
191 u32 inner_status_code;
225 (
"Advertise message arrived with NoAddrsAvail status code");
231 for (i = 0; i < n_addresses; i++)
236 address_info = &address_list[i];
237 address_info->
address = *address;
238 address_info->preferred_lt = 0;
239 address_info->valid_lt = 0;
254 clib_warning (
"Reply message arrived with Server ID different " 255 "from that in Request or Renew message");
261 clib_warning (
"Reply message arrived with NoAddrsAvail status code");
265 (
"Invalid Reply message arrived: It contains NoAddrsAvail " 266 "status code but also contains addresses");
273 clib_warning (
"Reply message arrived with UnspecFail status code");
280 for (i = 0; i < n_addresses; i++)
296 if (preferred_time > valid_time)
299 u8 address_already_present = 0;
303 if (address_info->sw_if_index != sw_if_index)
305 else if (!ip6_addresses_equal (&address_info->address, address))
309 address_already_present = 1;
310 goto address_pool_foreach_out;
314 address_pool_foreach_out:
316 if (address_already_present)
318 address_info->preferred_lt = preferred_time;
319 address_info->valid_lt = valid_time;
320 address_info->due_time = current_time;
322 address_info->due_time += (preferred_time > 0) ?
323 preferred_time : valid_time;
335 address_info->address = *
address;
336 address_info->preferred_lt = preferred_time;
337 address_info->valid_lt = valid_time;
338 address_info->due_time = current_time;
340 address_info->due_time += (preferred_time > 0) ?
341 preferred_time : valid_time;
348 &address_info->address, 64, 0);
353 client_state->server_index = server_index;
354 client_state->T1 = ntohl (mp->T1);
355 client_state->T2 = ntohl (mp->T2);
356 if (client_state->T1 != 0)
357 client_state->T1_due_time = current_time + client_state->T1;
358 if (client_state->T2 != 0)
359 client_state->T2_due_time = current_time + client_state->T2;
360 client_state->rebinding = 0;
376 if (address_info->sw_if_index == sw_if_index)
378 u32 pos = vec_len (address_list);
379 vec_validate (address_list, pos);
380 clib_memcpy (&address_list[pos], address_info, sizeof (*address_info));
397 f64 sleep_time = 1e9;
402 uword *event_data = 0;
421 due_time = current_time + 1e9;
425 if (address_info->due_time > current_time)
427 if (address_info->due_time < due_time)
428 due_time = address_info->due_time;
432 u32 sw_if_index = address_info->sw_if_index;
433 error = ip6_add_del_interface_address (vm, sw_if_index,
434 &address_info->address,
437 clib_warning (
"Failed to delete interface address");
438 pool_put (rm->address_pool, address_info);
440 ip6_enable (sw_if_index);
441 client_state = &rm->client_state_by_sw_if_index[sw_if_index];
442 if (--client_state->address_count == 0)
444 client_state->rebinding = 0;
445 client_state->server_index = ~0;
446 send_client_message_start_stop (sw_if_index, ~0,
494 while (due_time < current_time);
496 sleep_time = due_time - current_time;
506 .name =
"dhcp6-client-cp-process",
556 vlib_cli_output (vm,
"address: %U, " 557 "preferred lifetime: %u, valid lifetime: %u " 559 format_ip6_address, &address_info->address,
560 address_info->preferred_lt, address_info->valid_lt,
561 address_info->due_time - current_time);
570 .path =
"show dhcp6 addresses",
571 .short_help =
"show dhcp6 addresses",
587 const char *rebinding;
599 buf1 =
format (buf1,
"%u remaining",
603 buf1 =
format (buf1,
"timeout");
605 buf2 =
format (buf2,
"%u remaining",
608 buf2 =
format (buf2,
"timeout");
610 rebinding =
", REBINDING";
615 "sw_if_index: %u, T1: %u (%v), " 616 "T2: %u (%v), server index: %d%s", i,
617 cs->
T1, buf1, cs->
T2, buf2,
632 .path =
"show dhcp6 clients",
633 .short_help =
"show dhcp6 clients",
664 if (!old_enabled && enable)
677 else if (old_enabled && !enable)
691 if (address_info->sw_if_index == sw_if_index)
693 ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
694 rm->client_state_by_sw_if_index[sw_if_index].enabled);
695 client_state_t *client_state =
696 &rm->client_state_by_sw_if_index[sw_if_index];
697 send_client_message_start_stop (sw_if_index,
698 client_state->server_index,
699 DHCPV6_MSG_RELEASE, address_info,
701 error = ip6_add_del_interface_address (vm, sw_if_index,
702 &address_info->address,
705 clib_warning (
"Failed to delete interface address");
706 pool_put (rm->address_pool, address_info);
713 client_state->enabled = 0;
738 else if (
unformat (line_input,
"disable"))
750 if (sw_if_index != ~0)
776 .path =
"dhcp6 client",
777 .short_help =
"dhcp6 client <interface> [disable]",
786 vl_api_dhcp6_client_enable_disable_reply_t *rmp;
801 #define vl_msg_name_crc_list 802 #include <vnet/dhcp/dhcp6_ia_na_client_cp.api.h> 803 #undef vl_msg_name_crc_list 808 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); 809 foreach_vl_msg_name_crc_dhcp6_ia_na_client_cp;
825 vl_msg_api_set_handlers(VL_API_##N, #n, \ 826 vl_api_##n##_t_handler, \ 828 vl_api_##n##_t_endian, \ 829 vl_api_##n##_t_print, \ 830 sizeof(vl_api_##n##_t), 0); #define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static int dhcp6_client_enable_disable(u32 sw_if_index, u8 enable)
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...
vnet_main_t * vnet_get_main(void)
static f64 vlib_time_now(vlib_main_t *vm)
static void enable_process(void)
static u32 ip6_enable(u32 sw_if_index)
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 * dhcp_client_cp_init(vlib_main_t *vm)
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)
static void vl_api_dhcp6_client_enable_disable_t_handler(vl_api_dhcp6_client_enable_disable_t *mp)
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 BAD_SW_IF_INDEX_LABEL
#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...)
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
Enable/disable DHCPv6 client on interface.
#define VLIB_CLI_COMMAND(x,...)
Struct representing DHCPv6 address.
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 foreach_dhcp6_client_cp_msg
#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)
vlib_node_registration_t dhcp6_client_cp_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_client_cp_process_node)
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)
static void setup_message_id_table(api_main_t *am)
client_state_t * client_state_by_sw_if_index
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
#define VALIDATE_SW_IF_INDEX(mp)