-void
- vl_api_dhcp6_pd_send_client_message_t_handler
- (vl_api_dhcp6_pd_send_client_message_t * mp)
-{
- vl_api_dhcp6_pd_send_client_message_reply_t *rmp;
- dhcp6_pd_send_client_message_params_t params;
- vlib_main_t *vm = vlib_get_main ();
- u32 n_prefixes;
- u32 i;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_DHCP6_PD_SEND_CLIENT_MESSAGE_REPLY);
-
- if (rv != 0)
- return;
-
- params.sw_if_index = ntohl (mp->sw_if_index);
- params.server_index = ntohl (mp->server_index);
- params.irt = ntohl (mp->irt);
- params.mrt = ntohl (mp->mrt);
- params.mrc = ntohl (mp->mrc);
- params.mrd = ntohl (mp->mrd);
- params.msg_type = ntohl (mp->msg_type);
- params.T1 = ntohl (mp->T1);
- params.T2 = ntohl (mp->T2);
- n_prefixes = ntohl (mp->n_prefixes);
- params.prefixes = 0;
- if (n_prefixes > 0)
- vec_validate (params.prefixes, n_prefixes - 1);
- for (i = 0; i < n_prefixes; i++)
- {
- vl_api_dhcp6_pd_prefix_info_t *pi = &mp->prefixes[i];
- dhcp6_pd_send_client_message_params_prefix_t *pref =
- ¶ms.prefixes[i];
- pref->preferred_lt = ntohl (pi->preferred_time);
- pref->valid_lt = ntohl (pi->valid_time);
- ip6_address_decode (pi->prefix.address, &pref->prefix);
- pref->prefix_length = pi->prefix.len;
- }
-
- dhcp6_pd_send_client_message (vm, ntohl (mp->sw_if_index), mp->stop,
- ¶ms);
-}
-
-static clib_error_t *
-call_dhcp6_pd_reply_event_callbacks (void *data,
- _vnet_dhcp6_pd_reply_event_function_list_elt_t
- * elt)
-{
- clib_error_t *error = 0;
-
- while (elt)
- {
- error = elt->fp (data);
- if (error)
- return error;
- elt = elt->next_dhcp6_pd_reply_event_function;
- }
-
- return error;
-}
-
-static uword
-dhcp6_pd_reply_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
- vlib_frame_t * f)
-{
- /* These cross the longjmp boundary (vlib_process_wait_for_event)
- * and need to be volatile - to prevent them from being optimized into
- * a register - which could change during suspension */
-
- while (1)
- {
- vlib_process_wait_for_event (vm);
- uword event_type = DHCP6_PD_DP_REPLY_REPORT;
- void *event_data = vlib_process_get_event_data (vm, &event_type);
-
- int i;
- if (event_type == DHCP6_PD_DP_REPLY_REPORT)
- {
- prefix_report_t *events = event_data;
- for (i = 0; i < vec_len (events); i++)
- {
- u32 event_size =
- sizeof (vl_api_dhcp6_pd_reply_event_t) +
- vec_len (events[i].prefixes) *
- sizeof (vl_api_dhcp6_pd_prefix_info_t);
- vl_api_dhcp6_pd_reply_event_t *event =
- clib_mem_alloc (event_size);
- clib_memset (event, 0, event_size);
-
- event->sw_if_index = htonl (events[i].body.sw_if_index);
- event->server_index = htonl (events[i].body.server_index);
- event->msg_type = events[i].body.msg_type;
- event->T1 = htonl (events[i].body.T1);
- event->T2 = htonl (events[i].body.T2);
- event->inner_status_code =
- htons (events[i].body.inner_status_code);
- event->status_code = htons (events[i].body.status_code);
- event->preference = events[i].body.preference;
-
- event->n_prefixes = htonl (vec_len (events[i].prefixes));
- vl_api_dhcp6_pd_prefix_info_t *prefix =
- (typeof (prefix)) event->prefixes;
- u32 j;
- for (j = 0; j < vec_len (events[i].prefixes); j++)
- {
- dhcp6_prefix_info_t *info = &events[i].prefixes[j];
- ip6_address_encode (&info->prefix, prefix->prefix.address);
- prefix->prefix.len = info->prefix_length;
- prefix->valid_time = htonl (info->valid_time);
- prefix->preferred_time = htonl (info->preferred_time);
- prefix++;
- }
- vec_free (events[i].prefixes);
-
- dhcp6_pd_client_public_main_t *dpcpm =
- &dhcp6_pd_client_public_main;
- call_dhcp6_pd_reply_event_callbacks (event, dpcpm->functions);
-
- vpe_client_registration_t *reg;
- /* *INDENT-OFF* */
- pool_foreach(reg, vpe_api_main.dhcp6_pd_reply_events_registrations,
- ({
- vl_api_registration_t *vl_reg;
- vl_reg =
- vl_api_client_index_to_registration (reg->client_index);
- if (vl_reg && vl_api_can_send_msg (vl_reg))
- {
- vl_api_dhcp6_pd_reply_event_t *msg =
- vl_msg_api_alloc (event_size);
- clib_memcpy (msg, event, event_size);
- msg->_vl_msg_id = htons (VL_API_DHCP6_PD_REPLY_EVENT);
- msg->client_index = reg->client_index;
- msg->pid = reg->client_pid;
- vl_api_send_msg (vl_reg, (u8 *) msg);
- }
- }));
- /* *INDENT-ON* */
-
- clib_mem_free (event);
- }
- }
- vlib_process_put_event_data (vm, event_data);
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp6_pd_reply_process_node) = {
- .function = dhcp6_pd_reply_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp6-pd-reply-publisher-process",
-};
-/* *INDENT-ON* */
-
-void
- vl_api_want_dhcp6_pd_reply_events_t_handler
- (vl_api_want_dhcp6_pd_reply_events_t * mp)
-{
- vpe_api_main_t *am = &vpe_api_main;
- vl_api_want_dhcp6_pd_reply_events_reply_t *rmp;
- int rv = 0;
-
- uword *p =
- hash_get (am->dhcp6_pd_reply_events_registration_hash, mp->client_index);
- vpe_client_registration_t *rp;
- if (p)
- {
- if (mp->enable_disable)
- {
- clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- else
- {
- rp =
- pool_elt_at_index (am->dhcp6_pd_reply_events_registrations, p[0]);
- pool_put (am->dhcp6_pd_reply_events_registrations, rp);
- hash_unset (am->dhcp6_pd_reply_events_registration_hash,
- mp->client_index);
- if (pool_elts (am->dhcp6_pd_reply_events_registrations) == 0)
- dhcp6_pd_set_publisher_node (~0, DHCP6_PD_DP_REPORT_MAX);
- goto reply;
- }
- }
- if (mp->enable_disable == 0)
- {
- clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- pool_get (am->dhcp6_pd_reply_events_registrations, rp);
- rp->client_index = mp->client_index;
- rp->client_pid = ntohl (mp->pid);
- hash_set (am->dhcp6_pd_reply_events_registration_hash, rp->client_index,
- rp - am->dhcp6_pd_reply_events_registrations);
- dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
- DHCP6_PD_DP_REPLY_REPORT);
-
-reply:
- REPLY_MACRO (VL_API_WANT_DHCP6_PD_REPLY_EVENTS_REPLY);
-}
-