36 if (se->
len == len && 0 == memcmp (se->
data, data, len))
43 memcpy (new_se.
data, data, len);
53 vl_api_dhcp6_duid_ll_set_reply_t *rmp;
60 rv = VNET_API_ERROR_INVALID_VALUE;
63 clib_memcpy (&client_duid, &duid,
sizeof (client_duid));
73 client_duid.hardware_type = htons (1);
83 eth_if = ethernet_get_interface (ðernet_main, hi->hw_if_index);
94 "setting DHCPv6 DUID link-layer address to random value");
97 client_duid.lla[0] = 0xc2;
98 client_duid.lla[1] = 0x18;
99 client_duid.lla[2] = 0x44;
106 #define foreach_dhcpv6_client \ 107 _(DROP, "error-drop") \ 108 _(LOOKUP, "ip6-lookup") 112 #define _(sym,str) DHCPV6_CLIENT_NEXT_##sym, 132 s =
format (s,
"nothing");
144 dhcpv6_client_next_t next_index;
145 u32 n_left_from, *from, *to_next;
150 while (n_left_from > 0)
156 while (n_left_from > 0 && n_left_to_next > 0)
161 dhcpv6_option_t *option;
166 u32 next0 = DHCPV6_CLIENT_NEXT_DROP;
171 u8 client_id_present = 0;
189 u32 dhcpv6_ip6_palyoad_offset =
190 (
u8 *) dhcpv60 - ((
u8 *) ip0 +
sizeof (*ip0));
195 memset (&report, 0,
sizeof (report));
199 ia_na_client_state = 0;
209 (dhcpv60->
xid[0] << 16) + (dhcpv60->
xid[1] << 8) +
211 if (ia_na_client_state && ia_na_client_state->
transaction_id == xid)
213 else if (pd_client_state && pd_client_state->
transaction_id == xid)
218 (
"Received DHCPv6 message with wrong Transaction ID");
230 option = (dhcpv6_option_t *) (dhcpv60 + 1);
231 while (options_length > 0)
234 ntohs (option->length) +
sizeof (*option))
237 (
"remaining payload length < option length (%d < %d)",
239 ntohs (option->length) + sizeof (*option));
242 u16 oo = ntohs (option->option);
243 if (oo == DHCPV6_OPTION_IA_NA || oo == DHCPV6_OPTION_IA_PD)
245 u8 discard_option = 0;
246 dhcpv6_ia_header_t *ia_header = (
void *) option;
247 iaid = ntohl (ia_header->iaid);
248 u32 T1 = ntohl (ia_header->t1);
249 u32 T2 = ntohl (ia_header->t2);
252 if (T1 != 0 && T2 != 0 && T1 > T2)
259 dhcpv6_option_t *inner_option =
260 (
void *) ia_header->data;
261 u16 inner_options_length =
262 ntohs (option->length) - (
sizeof (*ia_header) -
263 sizeof (dhcpv6_option_t));
264 while (inner_options_length > 0)
266 u16 inner_oo = ntohs (inner_option->option);
269 else if (inner_oo == DHCPV6_OPTION_IAADDR)
271 dhcpv6_ia_opt_addr_t *iaaddr =
272 (
void *) inner_option;
276 &addresses[n_addresses];
278 ntohl (iaaddr->preferred);
280 ntohl (iaaddr->valid);
281 address_info->
address = iaaddr->addr;
283 else if (inner_oo == DHCPV6_OPTION_IAPREFIX)
285 dhcpv6_ia_opt_pd_t *iaprefix =
286 (
void *) inner_option;
290 &prefixes[n_prefixes];
292 ntohl (iaprefix->preferred);
294 ntohl (iaprefix->valid);
296 prefix_info->
prefix = iaprefix->addr;
298 else if (inner_oo == DHCPV6_OPTION_STATUS_CODE)
300 dhcpv6_status_code_t *sc =
301 (
void *) inner_option;
303 ntohs (sc->status_code);
305 inner_options_length -=
306 sizeof (*inner_option) +
307 ntohs (inner_option->length);
309 (
void *) ((
u8 *) inner_option +
310 sizeof (*inner_option) +
311 ntohs (inner_option->length));
314 else if (oo == DHCPV6_OPTION_CLIENTID)
316 if (client_id_present)
319 (
"Duplicate Client ID in received DHVPv6 message");
324 u16 len = ntohs (option->length);
325 client_id_present = 1;
327 0 != memcmp (option->data,
332 (
"Unrecognized client DUID inside received DHVPv6 message");
337 else if (oo == DHCPV6_OPTION_SERVERID)
342 (
"Duplicate Server ID in received DHVPv6 message");
347 u16 ol = ntohs (option->length);
351 (
"Server DUID (without type code) is longer than 128 octets");
361 else if (oo == DHCPV6_OPTION_PREFERENCE)
365 else if (oo == DHCPV6_OPTION_STATUS_CODE)
367 dhcpv6_status_code_t *sc = (
void *) option;
370 options_length -=
sizeof (*option) + ntohs (option->length);
372 (
void *) ((
u8 *) option +
sizeof (*option) +
373 ntohs (option->length));
376 if (!client_id_present)
379 (
"Missing Client ID in received DHVPv6 message");
385 (
"Missing Server ID in received DHVPv6 message");
422 dhcpv6_client_trace_t *t =
428 to_next, n_left_to_next,
441 .name =
"dhcpv6-client",
442 .vector_size =
sizeof (
u32),
448 #define _(s,n) [DHCPV6_CLIENT_NEXT_##s] = n, 464 if (client_duid.duid_type == 0)
478 vl_api_dhcp6_clients_enable_disable_reply_t *rmp;
483 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) ...
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
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 pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#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...)
#define clib_memcpy(a, b, c)
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)
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
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
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)