110 if (prefix_group_index >=
122 static const u32 empty = ~0;
124 ASSERT (prefix_group_index != ~0);
126 if (prefix_index == ~0
127 && prefix_group_index >=
132 prefix_group_index, empty);
206 i32 diff_time = client_state->
T2 - current_time;
209 params.
mrd = diff_time;
219 params.
mrd = diff_time;
229 if (
vec_len (prefix_list) != 0)
231 for (i = 0; i <
vec_len (prefix_list); i++)
237 pref->prefix = prefix->
prefix;
258 return clib_net_to_host_u64 (prefix1->
as_u64[1]) >> (128 -
len) ==
259 clib_net_to_host_u64 (prefix2->
as_u64[1]) >> (128 -
len);
261 return clib_net_to_host_u64 (prefix1->
as_u64[0]) >> (64 -
len) ==
262 clib_net_to_host_u64 (prefix2->
as_u64[0]) >> (64 -
len);
275 vl_api_dhcp6_pd_prefix_info_t *api_prefix;
276 u32 inner_status_code;
312 (
"Advertise message arrived with NoPrefixAvail status code");
318 for (i = 0; i < n_prefixes; i++)
322 prefix_length = api_prefix->prefix.len;
324 prefix_info = &prefix_list[i];
325 prefix_info->
prefix = *prefix;
343 clib_warning (
"Reply message arrived with Server ID different " 344 "from that in Request or Renew message");
350 clib_warning (
"Reply message arrived with NoPrefixAvail status code");
354 (
"Invalid Reply message arrived: It contains NoPrefixAvail " 355 "status code but also contains prefixes");
362 clib_warning (
"Reply message arrived with UnspecFail status code");
377 vec_add1 (pm->indices, prefix_info - pm->prefix_pool);
381 for (i = 0; i < n_prefixes; i++)
392 prefix_length = api_prefix->prefix.len;
397 valid_time = ntohl (api_prefix->valid_time);
398 preferred_time = ntohl (api_prefix->preferred_time);
399 prefix_length = api_prefix->prefix.len;
401 if (preferred_time > valid_time)
404 u8 address_prefix_present = 0;
417 address_prefix_present = 1;
422 if (address_prefix_present)
436 (prefix, prefix_length,
438 valid_time, preferred_time);
464 client_state->
T1 = ntohl (mp->
T1);
465 client_state->
T2 = ntohl (mp->
T2);
466 if (client_state->
T1 != 0)
468 if (client_state->
T2 != 0)
486 if (is_dhcpv6_pd_prefix (prefix_info) &&
487 prefix_info->opaque_data == sw_if_index)
489 u32 pos = vec_len (prefix_list);
490 vec_validate (prefix_list, pos);
491 clib_memcpy (&prefix_list[pos], prefix_info, sizeof (*prefix_info));
509 f64 sleep_time = 1e9;
513 uword *event_data = 0;
532 due_time = current_time + 1e9;
536 if (is_dhcpv6_pd_prefix (prefix_info))
538 if (prefix_info->due_time > current_time)
540 if (prefix_info->due_time < due_time)
541 due_time = prefix_info->due_time;
545 u32 prefix_index = prefix_info - pm->prefix_pool;
546 notify_prefix_add_del (prefix_index, 0);
547 u32 sw_if_index = prefix_info->opaque_data;
548 set_is_dhcpv6_pd_prefix (prefix_info, 0);
549 pool_put (pm->prefix_pool, prefix_info);
550 client_state = &rm->client_state_by_sw_if_index[sw_if_index];
551 if (--client_state->prefix_count == 0)
553 client_state->rebinding = 0;
554 client_state->server_index = ~0;
555 send_client_message_start_stop (sw_if_index, ~0,
603 while (due_time < current_time);
605 sleep_time = due_time - current_time;
615 .name =
"dhcp6-pd-client-cp-process",
658 u64 mask, addr0, pref;
660 addr0 = clib_net_to_host_u64 (address_info->
address.
as_u64[0]);
672 r_addr->
as_u64[0] = clib_host_to_net_u64 (addr0);
695 if (prefix_index != ~0)
748 if (prefix_index == ~0)
764 "but active prefix index is not set");
785 u32 ignore_prefix_index)
793 if (prefix_info->prefix_group_index == prefix_group_index &&
794 prefix_info - pm->prefix_pool != ignore_prefix_index)
795 return prefix_info - pm->prefix_pool;
836 clib_warning (
"ip6_neighbor_ra_prefix returned %d", rv);
841 clib_warning (
"Advertise prefix %U valid lt %u preferred lt %u",
855 u32 new_prefix_index;
856 u32 prefix_group_index;
865 (prefix_group_index) == ~0)
868 (prefix_group_index, prefix_index);
886 (prefix_group_index) == prefix_index)
899 (prefix_group_index, ~0);
903 if (new_prefix_index != ~0)
906 (prefix_group_index, new_prefix_index);
936 (
const char *) name))
941 name_dup = (
u8 *) strdup ((
const char *)
name);
942 if (free_index != ~0)
963 u32 prefix_group_index;
969 return VNET_API_ERROR_INVALID_VALUE;
972 if (prefix_group != 0 && prefix_group[0] !=
'\0')
974 if (strnlen ((
const char *) prefix_group, 64) == 64)
975 return VNET_API_ERROR_INVALID_VALUE;
980 prefix_group_index = ~0;
989 0 == memcmp (&address_info->
address, &address, 16))
992 return VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
1001 return VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
1022 u8 *prefix_group = 0;
1036 else if (
unformat (line_input,
"prefix group %s", &prefix_group));
1039 &address, &prefix_length))
1041 else if (
unformat (line_input,
"del"))
1054 if (sw_if_index == ~0)
1056 else if (address_set == 0)
1061 (sw_if_index, prefix_group, address, prefix_length, add) != 0)
1085 .path =
"set ip6 address",
1086 .short_help =
"set ip6 address <interface> [prefix group <string>] " 1100 const u8 *prefix_group;
1108 prefix_group = (
const u8 *)
"NONE";
1113 "sw_if_index: %u, prefix_group: %s, address: %U/%d",
1124 .path =
"show ip6 addresses",
1125 .short_help =
"show ip6 addresses",
1138 const u8 *prefix_group;
1145 pm->prefix_group_name_by_index[prefix_info->prefix_group_index];
1146 vlib_cli_output (vm,
"opaque_data: %lu, prefix: %U/%d, prefix group: %s, " 1147 "preferred lifetime: %u, valid lifetime: %u " 1149 prefix_info->opaque_data, format_ip6_address,
1150 &prefix_info->prefix, prefix_info->prefix_length,
1152 prefix_info->preferred_lt, prefix_info->valid_lt,
1153 prefix_info->due_time - current_time);
1162 .path =
"show ip6 prefixes",
1163 .short_help =
"show ip6 prefixes",
1178 const u8 *prefix_group;
1181 const char *rebinding;
1191 sprintf (buf1,
"%u remaining",
1195 sprintf (buf1,
"timeout");
1197 sprintf (buf2,
"%u remaining",
1200 sprintf (buf2,
"timeout");
1202 rebinding =
", REBINDING";
1209 "sw_if_index: %u, prefix group: %s, T1: %u (%s), " 1210 "T2: %u (%s), server index: %d%s", i,
1211 prefix_group, cs->
T1, buf1, cs->
T2, buf2,
1215 prefix_group, rebinding);
1224 .path =
"show ip6 pd clients",
1225 .short_help =
"show ip6 pd clients",
1234 const u8 * prefix_group,
u8 enable)
1245 u32 prefix_group_index;
1250 return VNET_API_ERROR_INVALID_VALUE;
1261 if (strnlen ((
const char *) prefix_group, 64) == 64
1262 || prefix_group[0] ==
'\0')
1263 return VNET_API_ERROR_INVALID_VALUE;
1264 prefix_group_index =
1268 return VNET_API_ERROR_INVALID_VALUE;
1271 if (!old_enabled && enable)
1289 else if (old_enabled && !enable)
1305 if (is_dhcpv6_pd_prefix (prefix_info) &&
1306 prefix_info->opaque_data == sw_if_index)
1308 ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
1309 rm->client_state_by_sw_if_index[sw_if_index].enabled);
1310 client_state_t *client_state =
1311 &rm->client_state_by_sw_if_index[sw_if_index];
1312 prefix_list[0] = *prefix_info;
1313 send_client_message_start_stop (sw_if_index,
1314 client_state->server_index,
1315 DHCPV6_MSG_RELEASE, prefix_list,
1317 u32 prefix_index = prefix_info - pm->prefix_pool;
1318 notify_prefix_add_del (prefix_index, 0);
1319 set_is_dhcpv6_pd_prefix (prefix_info, 0);
1320 pool_put (pm->prefix_pool, prefix_info);
1327 clib_memset (client_state, 0,
sizeof (*client_state));
1342 u8 *prefix_group = 0;
1355 else if (
unformat (line_input,
"prefix group %s", &prefix_group));
1356 else if (
unformat (line_input,
"disable"))
1366 if (prefix_group == 0 && enable)
1368 else if (sw_if_index != ~0)
1398 .path =
"dhcp6 pd client",
1399 .short_help =
"dhcp6 pd client <interface> (prefix group <string> | disable)",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u8 * format_clib_error(u8 *s, va_list *va)
static void notify_prefix_add_del(u32 prefix_index, u8 is_add)
vlib_node_registration_t dhcp6_pd_client_cp_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_pd_client_cp_process_node)
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)
vl_api_dhcp6_pd_prefix_info_t prefixes[n_prefixes]
static void cp_ip6_address_prefix_add_del_handler(u32 prefix_index, u8 is_add)
int dhcp6_pd_client_enable_disable(u32 sw_if_index, const u8 *prefix_group, u8 enable)
Optimized string handling code, including c11-compliant "safe C library" variants.
static u32 cp_ip6_address_find_new_active_prefix(u32 prefix_group_index, u32 ignore_prefix_index)
static_always_inline u8 is_dhcpv6_pd_prefix(prefix_info_t *prefix_info)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void send_client_message_start_stop(u32 sw_if_index, u32 server_index, u8 msg_type, prefix_info_t *prefix_list, u8 start)
static f64 vlib_time_now(vlib_main_t *vm)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
dhcp6_pd_send_client_message_params_prefix_t * prefixes
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
void dhcp6_pd_send_client_message(vlib_main_t *vm, u32 sw_if_index, u8 stop, dhcp6_pd_send_client_message_params_t *params)
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
format_function_t format_vnet_sw_if_index_name
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static ip6_address_with_prefix_main_t ip6_address_with_prefix_main
const u8 ** prefix_group_name_by_index
static void cp_ip6_address_add_del_now(ip6_address_info_t *address_info, u8 is_add)
#define static_always_inline
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
ip6_address_info_t * addresses
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...
#define clib_error_return(e, args...)
vl_api_dhcpv6_msg_type_t msg_type
static_always_inline void active_prefix_index_by_prefix_group_index_set(u32 prefix_group_index, u32 prefix_index)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
VNET_DHCP6_PD_REPLY_EVENT_FUNCTION(dhcp6_pd_reply_event_handler)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
u32 * active_prefix_index_by_prefix_group_index
int ip6_link_enable(u32 sw_if_index)
IPv6 Configuration on an interface.
static void interrupt_process(void)
static void disable_process(void)
API main structure, used by both vpp and binary API clients.
ip6_address_t fib_masks[129]
#define VLIB_REGISTER_NODE(x,...)
static clib_error_t * cp_ip6_prefixes_show_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * ip6_pd_clients_show_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vl_api_interface_index_t sw_if_index
#define vec_free(V)
Free vector's memory (no header).
static prefix_info_t * create_prefix_list(u32 sw_if_index)
#define clib_warning(format, args...)
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
vlib_main_t vlib_node_runtime_t * node
#define VLIB_CLI_COMMAND(x,...)
static u32 cp_ip6_construct_address(ip6_address_info_t *address_info, u32 prefix_index, ip6_address_t *r_addr)
void ip6_ra_update_secondary_radv_info(ip6_address_t *address, u8 prefix_len, u32 primary_sw_if_index, u32 valid_time, u32 preferred_time)
manual_print typedef address
static_always_inline u32 active_prefix_index_by_prefix_group_index_get(u32 prefix_group_index)
static u8 ip6_prefixes_equal(ip6_address_t *prefix1, ip6_address_t *prefix2, u8 len)
Tell client about a DHCPv6 PD server reply event.
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)
static clib_error_t * dhcp6_pd_reply_event_handler(vl_api_dhcp6_pd_reply_event_t *mp)
static vlib_main_t * vlib_get_main(void)
#define vec_elt(v, i)
Get vector value at index i.
static dhcp6_pd_client_cp_main_t dhcp6_pd_client_cp_main
prefix_info_t * prefix_pool
static_always_inline void set_is_dhcpv6_pd_prefix(prefix_info_t *prefix_info, u8 value)
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
u8 configured_in_data_plane
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * cp_ip6_addresses_show_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vlib_node_main_t node_main
static clib_error_t * dhcp_pd_client_cp_init(vlib_main_t *vm)
static uword dhcp6_pd_client_cp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static u32 prefix_group_find_or_create(const u8 *name, u8 create)
void dhcp6_clients_enable_disable(u8 enable)
static api_main_t * vlibapi_get_main(void)
int ip6_ra_prefix(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *prefix_addr, u8 prefix_len, u8 use_default, u32 val_lifetime, u32 pref_lifetime, u8 no_advertise, u8 off_link, u8 no_autoconfig, u8 no_onlink, u8 is_no)
clib_bitmap_t * prefix_ownership_bitmap
#define vec_foreach(var, vec)
Vector iterator.
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)
static vlib_cli_command_t dhcp6_pd_client_enable_disable_command
(constructor) VLIB_CLI_COMMAND (dhcp6_pd_client_enable_disable_command)
#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 void cp_ip6_advertise_prefix(prefix_info_t *prefix_info, ip6_address_info_t *address_info, int enable)
int dhcp6_cp_ip6_address_add_del(u32 sw_if_index, const u8 *prefix_group, ip6_address_t address, u8 prefix_length, u8 is_add)
void vlib_start_process(vlib_main_t *vm, uword process_index)
static void enable_process(void)
static ip6_prefix_main_t ip6_prefix_main
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static clib_error_t * dhcp6_pd_client_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t() *input, vlib_cli_command_t *cmd)
static clib_error_t * cp_ip6_address_add_del_command_function(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
client_state_t * client_state_by_sw_if_index