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 + valid_time;
331 address_info->address = *
address;
332 address_info->preferred_lt = preferred_time;
333 address_info->valid_lt = valid_time;
334 address_info->due_time = current_time + valid_time;
340 &address_info->address, 64, 0);
345 client_state->server_index = server_index;
346 client_state->T1 = ntohl (mp->T1);
347 client_state->T2 = ntohl (mp->T2);
348 if (client_state->T1 != 0)
349 client_state->T1_due_time = current_time + client_state->T1;
350 if (client_state->T2 != 0)
351 client_state->T2_due_time = current_time + client_state->T2;
352 client_state->rebinding = 0;
368 if (address_info->sw_if_index == sw_if_index)
370 u32 pos = vec_len (address_list);
371 vec_validate (address_list, pos);
372 clib_memcpy (&address_list[pos], address_info, sizeof (*address_info));
389 f64 sleep_time = 1e9;
394 uword *event_data = 0;
413 due_time = current_time + 1e9;
417 if (address_info->due_time > current_time)
419 if (address_info->due_time < due_time)
420 due_time = address_info->due_time;
424 u32 sw_if_index = address_info->sw_if_index;
425 error = ip6_add_del_interface_address (vm, sw_if_index,
426 &address_info->address,
429 clib_warning (
"Failed to delete interface address");
430 pool_put (rm->address_pool, address_info);
432 ip6_enable (sw_if_index);
433 client_state = &rm->client_state_by_sw_if_index[sw_if_index];
434 if (--client_state->address_count == 0)
436 client_state->rebinding = 0;
437 client_state->server_index = ~0;
438 send_client_message_start_stop (sw_if_index, ~0,
486 while (due_time < current_time);
488 sleep_time = due_time - current_time;
498 .name =
"dhcp6-client-cp-process",
548 vlib_cli_output (vm,
"address: %U, " 549 "preferred lifetime: %u, valid lifetime: %u " 551 format_ip6_address, &address_info->address,
552 address_info->preferred_lt, address_info->valid_lt,
553 address_info->due_time - current_time);
562 .path =
"show dhcp6 addresses",
563 .short_help =
"show dhcp6 addresses",
579 const char *rebinding;
589 sprintf (buf1,
"%u remaining",
593 sprintf (buf1,
"timeout");
595 sprintf (buf2,
"%u remaining",
598 sprintf (buf2,
"timeout");
600 rebinding =
", REBINDING";
605 "sw_if_index: %u, T1: %u (%s), " 606 "T2: %u (%s), server index: %d%s", i,
607 cs->
T1, buf1, cs->
T2, buf2,
619 .path =
"show dhcp6 clients",
620 .short_help =
"show dhcp6 clients",
651 if (!old_enabled && enable)
664 else if (old_enabled && !enable)
678 if (address_info->sw_if_index == sw_if_index)
680 ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
681 rm->client_state_by_sw_if_index[sw_if_index].enabled);
682 client_state_t *client_state =
683 &rm->client_state_by_sw_if_index[sw_if_index];
684 send_client_message_start_stop (sw_if_index,
685 client_state->server_index,
686 DHCPV6_MSG_RELEASE, address_info,
688 error = ip6_add_del_interface_address (vm, sw_if_index,
689 &address_info->address,
692 clib_warning (
"Failed to delete interface address");
693 pool_put (rm->address_pool, address_info);
700 client_state->enabled = 0;
721 else if (
unformat (input,
"disable"))
731 if (sw_if_index != ~0)
757 .path =
"dhcp6 client",
758 .short_help =
"dhcp6 client <interface> [disable]",
767 vl_api_dhcp6_client_enable_disable_reply_t *rmp;
782 #define vl_msg_name_crc_list 783 #include <vnet/dhcp/dhcp6_ia_na_client_cp.api.h> 784 #undef vl_msg_name_crc_list 789 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); 790 foreach_vl_msg_name_crc_dhcp6_ia_na_client_cp;
806 vl_msg_api_set_handlers(VL_API_##N, #n, \ 807 vl_api_##n##_t_handler, \ 809 vl_api_##n##_t_endian, \ 810 vl_api_##n##_t_print, \ 811 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.
#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)