37 if (se->
len == len && 0 == memcmp (se->
data, data, len))
44 memcpy (new_se.
data, data, len);
54 vl_api_dhcp6_duid_ll_set_reply_t *rmp;
61 rv = VNET_API_ERROR_INVALID_VALUE;
64 clib_memcpy (&client_duid, &duid,
sizeof (client_duid));
74 client_duid.hardware_type = htons (1);
84 eth_if = ethernet_get_interface (ðernet_main, hi->hw_if_index);
95 "setting DHCPv6 DUID link-layer address to random value");
98 client_duid.lla[0] = 0xc2;
99 client_duid.lla[1] = 0x18;
100 client_duid.lla[2] = 0x44;
107 #define foreach_dhcpv6_client \ 108 _(DROP, "error-drop") \ 109 _(LOOKUP, "ip6-lookup") 113 #define _(sym,str) DHCPV6_CLIENT_NEXT_##sym, 133 s =
format (s,
"nothing");
145 dhcpv6_client_next_t next_index;
146 u32 n_left_from, *from, *to_next;
151 while (n_left_from > 0)
157 while (n_left_from > 0 && n_left_to_next > 0)
162 dhcpv6_option_t *option;
167 u32 next0 = DHCPV6_CLIENT_NEXT_DROP;
172 u8 client_id_present = 0;
190 u32 dhcpv6_ip6_payload_offset =
191 (
u8 *) dhcpv60 - ((
u8 *) ip0 +
sizeof (*ip0));
200 ia_na_client_state = 0;
210 (dhcpv60->
xid[0] << 16) + (dhcpv60->
xid[1] << 8) +
212 if (ia_na_client_state && ia_na_client_state->
transaction_id == xid)
214 else if (pd_client_state && pd_client_state->
transaction_id == xid)
219 (
"Received DHCPv6 message with wrong Transaction ID");
231 option = (dhcpv6_option_t *) (dhcpv60 + 1);
232 while (options_length > 0)
235 ntohs (option->length) +
sizeof (*option))
238 (
"remaining payload length < option length (%d < %d)",
240 ntohs (option->length) + sizeof (*option));
243 u16 oo = ntohs (option->option);
244 if (oo == DHCPV6_OPTION_IA_NA || oo == DHCPV6_OPTION_IA_PD)
246 u8 discard_option = 0;
247 dhcpv6_ia_header_t *ia_header = (
void *) option;
248 iaid = ntohl (ia_header->iaid);
249 u32 T1 = ntohl (ia_header->t1);
250 u32 T2 = ntohl (ia_header->t2);
253 if (T1 != 0 && T2 != 0 && T1 > T2)
260 dhcpv6_option_t *inner_option =
261 (
void *) ia_header->data;
262 u16 inner_options_length =
263 ntohs (option->length) - (
sizeof (*ia_header) -
264 sizeof (dhcpv6_option_t));
265 while (inner_options_length > 0)
267 u16 inner_oo = ntohs (inner_option->option);
270 else if (inner_oo == DHCPV6_OPTION_IAADDR)
272 dhcpv6_ia_opt_addr_t *iaaddr =
273 (
void *) inner_option;
277 &addresses[n_addresses];
279 ntohl (iaaddr->preferred);
281 ntohl (iaaddr->valid);
282 address_info->
address = iaaddr->addr;
284 else if (inner_oo == DHCPV6_OPTION_IAPREFIX)
286 dhcpv6_ia_opt_pd_t *iaprefix =
287 (
void *) inner_option;
291 &prefixes[n_prefixes];
293 ntohl (iaprefix->preferred);
295 ntohl (iaprefix->valid);
297 prefix_info->
prefix = iaprefix->addr;
299 else if (inner_oo == DHCPV6_OPTION_STATUS_CODE)
301 dhcpv6_status_code_t *sc =
302 (
void *) inner_option;
304 ntohs (sc->status_code);
306 inner_options_length -=
307 sizeof (*inner_option) +
308 ntohs (inner_option->length);
310 (
void *) ((
u8 *) inner_option +
311 sizeof (*inner_option) +
312 ntohs (inner_option->length));
315 else if (oo == DHCPV6_OPTION_CLIENTID)
317 if (client_id_present)
320 (
"Duplicate Client ID in received DHVPv6 message");
325 u16 len = ntohs (option->length);
326 client_id_present = 1;
328 0 != memcmp (option->data,
333 (
"Unrecognized client DUID inside received DHVPv6 message");
338 else if (oo == DHCPV6_OPTION_SERVERID)
343 (
"Duplicate Server ID in received DHVPv6 message");
348 u16 ol = ntohs (option->length);
352 (
"Server DUID (without type code) is longer than 128 octets");
362 else if (oo == DHCPV6_OPTION_PREFERENCE)
366 else if (oo == DHCPV6_OPTION_STATUS_CODE)
368 dhcpv6_status_code_t *sc = (
void *) option;
371 options_length -=
sizeof (*option) + ntohs (option->length);
373 (
void *) ((
u8 *) option +
sizeof (*option) +
374 ntohs (option->length));
377 if (!client_id_present)
380 (
"Missing Client ID in received DHVPv6 message");
386 (
"Missing Server ID in received DHVPv6 message");
423 dhcpv6_client_trace_t *t =
429 to_next, n_left_to_next,
442 .name =
"dhcpv6-client",
443 .vector_size =
sizeof (
u32),
449 #define _(s,n) [DHCPV6_CLIENT_NEXT_##s] = n, 465 if (client_duid.duid_type == 0)
479 vl_api_dhcp6_clients_enable_disable_reply_t *rmp;
484 REPLY_MACRO (VL_API_DHCP6_CLIENTS_ENABLE_DISABLE_REPLY);
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Enable/disable listening on DHCPv6 client port.
static vlib_node_registration_t dhcpv6_client_node
(constructor) VLIB_REGISTER_NODE (dhcpv6_client_node)
static uword random_default_seed(void)
Default random seed (unix/linux user-mode)
dhcp6_pd_client_main_t dhcp6_pd_client_main
vnet_main_t * vnet_get_main(void)
vnet_interface_main_t interface_main
dhcp6_pd_client_state_t * client_state_by_sw_if_index
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void generate_client_duid(void)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
int dhcp6_pd_publish_report(prefix_report_t *r)
#define clib_memcpy(d, s, n)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vl_api_interface_index_t sw_if_index
#define foreach_dhcpv6_client
vnet_hw_interface_t * hw_interfaces
dhcp6_ia_na_client_main_t dhcp6_ia_na_client_main
u32 server_index_get_or_create(u8 *data, u16 len)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
dhcp6_ia_na_client_state_t * client_state_by_sw_if_index
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void vl_api_dhcp6_duid_ll_set_t_handler(vl_api_dhcp6_duid_ll_set_t *mp)
dhcpv6_duid_ll_string_t client_duid
#define CLIENT_DUID_LENGTH
#define VLIB_REGISTER_NODE(x,...)
#define DHCPV6_CLIENT_IAID
#define vec_free(V)
Free vector's memory (no header).
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
#define clib_warning(format, args...)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
struct dhcpv6_client_trace_t_ dhcpv6_client_trace_t
per-packet trace data
dhcp6_report_common_t body
void vl_api_dhcp6_clients_enable_disable_t_handler(vl_api_dhcp6_clients_enable_disable_t *mp)
static vlib_main_t * vlib_get_main(void)
dhcp6_client_common_main_t dhcp6_client_common_main
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int dhcp6_publish_report(address_report_t *r)
VLIB buffer representation.
dhcp6_address_info_t * addresses
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
void dhcp6_clients_enable_disable(u8 enable)
static u32 random_u32(u32 *seed)
32-bit random number generator
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
dhcp6_report_common_t body
static uword dhcpv6_client_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
dhcp6_prefix_info_t * prefixes
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static u8 * format_dhcpv6_client_trace(u8 *s, va_list *args)