X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdhcp%2Fdhcp_api.c;h=7935ad8ba0154fde46a0ba8455dcf72ec489cd5c;hb=038e1dfbd;hp=bdf02cae799dfa77271dab396b9a3697d934b7b0;hpb=2dd6852d8109e39d15a5c60f7ba58f1abcf9e455;p=vpp.git diff --git a/src/vnet/dhcp/dhcp_api.c b/src/vnet/dhcp/dhcp_api.c index bdf02cae799..7935ad8ba01 100644 --- a/src/vnet/dhcp/dhcp_api.c +++ b/src/vnet/dhcp/dhcp_api.c @@ -24,6 +24,11 @@ #include #include #include +#include +#include +#include +#include +#include #include @@ -46,23 +51,31 @@ #define foreach_vpe_api_msg \ _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \ _(DHCP_PROXY_DUMP,dhcp_proxy_dump) \ -_(DHCP_PROXY_DETAILS,dhcp_proxy_details) \ _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \ -_(DHCP_CLIENT_CONFIG, dhcp_client_config) +_(DHCP_CLIENT_CONFIG, dhcp_client_config) \ +_(DHCP_CLIENT_DUMP, dhcp_client_dump) \ +_(WANT_DHCP6_PD_REPLY_EVENTS, want_dhcp6_pd_reply_events) \ +_(DHCP6_PD_SEND_CLIENT_MESSAGE, dhcp6_pd_send_client_message) \ +_(WANT_DHCP6_REPLY_EVENTS, want_dhcp6_reply_events) \ +_(DHCP6_SEND_CLIENT_MESSAGE, dhcp6_send_client_message) \ +_(DHCP6_CLIENTS_ENABLE_DISABLE, dhcp6_clients_enable_disable) \ +_(DHCP6_DUID_LL_SET, dhcp6_duid_ll_set) static void vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp) { vl_api_dhcp_proxy_set_vss_reply_t *rmp; + u8 *vpn_ascii_id; int rv; - rv = dhcp_proxy_set_vss ((mp->is_ipv6 ? - FIB_PROTOCOL_IP6 : - FIB_PROTOCOL_IP4), - ntohl (mp->tbl_id), - ntohl (mp->oui), - ntohl (mp->fib_id), (int) mp->is_add == 0); + mp->vpn_ascii_id[sizeof (mp->vpn_ascii_id) - 1] = 0; + vpn_ascii_id = format (0, "%s", mp->vpn_ascii_id); + rv = + dhcp_proxy_set_vss ((mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4), + ntohl (mp->tbl_id), mp->vss_type, vpn_ascii_id, + ntohl (mp->oui), ntohl (mp->vpn_index), + mp->is_add == 0); REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY); } @@ -108,90 +121,171 @@ static void vl_api_dhcp_proxy_config_t_handler static void vl_api_dhcp_proxy_dump_t_handler (vl_api_dhcp_proxy_dump_t * mp) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - return; + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return;; - dhcp_proxy_dump ((mp->is_ip6 == 0 ? - FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4), q, mp->context); + dhcp_proxy_dump ((mp->is_ip6 == 1 ? + FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4), reg, mp->context); } void dhcp_send_details (fib_protocol_t proto, - void *opaque, - u32 context, - const ip46_address_t * server, - const ip46_address_t * src, - u32 server_fib_id, - u32 rx_fib_id, u32 vss_fib_id, u32 vss_oui) + void *opaque, u32 context, dhcp_proxy_t * proxy) { vl_api_dhcp_proxy_details_t *mp; - unix_shared_memory_queue_t *q = opaque; - - mp = vl_msg_api_alloc (sizeof (*mp)); + vl_api_registration_t *reg = opaque; + vl_api_dhcp_server_t *v_server; + dhcp_server_t *server; + fib_table_t *s_fib; + dhcp_vss_t *vss; + u32 count; + size_t n; + + count = vec_len (proxy->dhcp_servers); + n = sizeof (*mp) + (count * sizeof (vl_api_dhcp_server_t)); + mp = vl_msg_api_alloc (n); if (!mp) return; - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, n); mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_DETAILS); mp->context = context; - - mp->rx_vrf_id = htonl (rx_fib_id); - mp->server_vrf_id = htonl (server_fib_id); - mp->vss_oui = htonl (vss_oui); - mp->vss_fib_id = htonl (vss_fib_id); + mp->count = count; mp->is_ipv6 = (proto == FIB_PROTOCOL_IP6); + mp->rx_vrf_id = + htonl (dhcp_proxy_rx_table_get_table_id (proto, proxy->rx_fib_index)); + + vss = dhcp_get_vss_info (&dhcp_proxy_main, proxy->rx_fib_index, proto); + + if (vss) + { + mp->vss_type = vss->vss_type; + if (vss->vss_type == VSS_TYPE_ASCII) + { + u32 id_len = vec_len (vss->vpn_ascii_id); + clib_memcpy (mp->vss_vpn_ascii_id, vss->vpn_ascii_id, id_len); + } + else if (vss->vss_type == VSS_TYPE_VPN_ID) + { + u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8) + + ((u32) vss->vpn_id[2]); + u32 fib_id = ((u32) vss->vpn_id[3] << 24) + + ((u32) vss->vpn_id[4] << 16) + ((u32) vss->vpn_id[5] << 8) + + ((u32) vss->vpn_id[6]); + mp->vss_oui = htonl (oui); + mp->vss_fib_id = htonl (fib_id); + } + } + else + mp->vss_type = VSS_TYPE_INVALID; + + vec_foreach_index (count, proxy->dhcp_servers) + { + server = &proxy->dhcp_servers[count]; + v_server = &mp->servers[count]; + + s_fib = fib_table_get (server->server_fib_index, proto); + + v_server->server_vrf_id = htonl (s_fib->ft_table_id); + + if (mp->is_ipv6) + { + memcpy (v_server->dhcp_server, &server->dhcp_server.ip6, 16); + } + else + { + /* put the address in the first bytes */ + memcpy (v_server->dhcp_server, &server->dhcp_server.ip4, 4); + } + } if (mp->is_ipv6) { - memcpy (mp->dhcp_server, server, 16); - memcpy (mp->dhcp_src_address, src, 16); + memcpy (mp->dhcp_src_address, &proxy->dhcp_src_address.ip6, 16); } else { /* put the address in the first bytes */ - memcpy (mp->dhcp_server, &server->ip4, 4); - memcpy (mp->dhcp_src_address, &src->ip4, 4); + memcpy (mp->dhcp_src_address, &proxy->dhcp_src_address.ip4, 4); } - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_api_send_msg (reg, (u8 *) mp); } +static void +dhcp_client_lease_encode (vl_api_dhcp_lease_t * lease, + const dhcp_client_t * client) +{ + size_t len; + u8 i; + + lease->is_ipv6 = 0; // only support IPv6 clients + lease->sw_if_index = ntohl (client->sw_if_index); + lease->state = client->state; + len = clib_min (sizeof (lease->hostname) - 1, vec_len (client->hostname)); + clib_memcpy (&lease->hostname, client->hostname, len); + lease->hostname[len] = 0; + + lease->mask_width = client->subnet_mask_width; + clib_memcpy (&lease->host_address[0], (u8 *) & client->leased_address, + sizeof (ip4_address_t)); + clib_memcpy (&lease->router_address[0], (u8 *) & client->router_address, + sizeof (ip4_address_t)); + + lease->count = vec_len (client->domain_server_address); + for (i = 0; i < lease->count; i++) + clib_memcpy (&lease->domain_server[i].address, + (u8 *) & client->domain_server_address[i], + sizeof (ip4_address_t)); + + clib_memcpy (&lease->host_mac[0], client->client_hardware_address, 6); +} static void -vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp) +dhcp_client_data_encode (vl_api_dhcp_client_t * vclient, + const dhcp_client_t * client) { - clib_warning ("BUG"); + size_t len; + + vclient->sw_if_index = ntohl (client->sw_if_index); + len = clib_min (sizeof (vclient->hostname) - 1, vec_len (client->hostname)); + clib_memcpy (&vclient->hostname, client->hostname, len); + vclient->hostname[len] = 0; + + len = clib_min (sizeof (vclient->id) - 1, + vec_len (client->client_identifier)); + clib_memcpy (&vclient->id, client->client_identifier, len); + vclient->id[len] = 0; + + if (NULL != client->event_callback) + vclient->want_dhcp_event = 1; + else + vclient->want_dhcp_event = 0; + vclient->set_broadcast_flag = client->set_broadcast_flag; + vclient->dscp = ip_dscp_encode (client->dscp); + vclient->pid = client->pid; } -void -dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname, - u8 is_ipv6, u8 * host_address, u8 * router_address, - u8 * host_mac) +static void +dhcp_compl_event_callback (u32 client_index, const dhcp_client_t * client) { - unix_shared_memory_queue_t *q; + vl_api_registration_t *reg; vl_api_dhcp_compl_event_t *mp; - q = vl_api_client_index_to_input_queue (client_index); - if (!q) + reg = vl_api_client_index_to_registration (client_index); + if (!reg) return; mp = vl_msg_api_alloc (sizeof (*mp)); mp->client_index = client_index; - mp->pid = pid; - mp->is_ipv6 = is_ipv6; - clib_memcpy (&mp->hostname, hostname, vec_len (hostname)); - mp->hostname[vec_len (hostname) + 1] = '\n'; - clib_memcpy (&mp->host_address[0], host_address, 16); - clib_memcpy (&mp->router_address[0], router_address, 16); - - if (NULL != host_mac) - clib_memcpy (&mp->host_mac[0], host_mac, 6); + mp->pid = client->pid; + dhcp_client_lease_encode (&mp->lease, client); mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_api_send_msg (reg, (u8 *) mp); } static void vl_api_dhcp_client_config_t_handler @@ -199,24 +293,79 @@ static void vl_api_dhcp_client_config_t_handler { vlib_main_t *vm = vlib_get_main (); vl_api_dhcp_client_config_reply_t *rmp; + u32 sw_if_index; + ip_dscp_t dscp; int rv = 0; - VALIDATE_SW_IF_INDEX (mp); + VALIDATE_SW_IF_INDEX (&(mp->client)); - rv = dhcp_client_config (vm, ntohl (mp->sw_if_index), - mp->hostname, mp->is_add, mp->client_index, - mp->want_dhcp_event ? dhcp_compl_event_callback : - NULL, mp->pid); + sw_if_index = ntohl (mp->client.sw_if_index); + dscp = ip_dscp_decode (mp->client.dscp); - BAD_SW_IF_INDEX_LABEL; + rv = dhcp_client_config (mp->is_add, + mp->client_index, + vm, + sw_if_index, + mp->client.hostname, + mp->client.id, + (mp->client.want_dhcp_event ? + dhcp_compl_event_callback : + NULL), + mp->client.set_broadcast_flag, + dscp, mp->client.pid); + BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY); } +typedef struct dhcp_client_send_walk_ctx_t_ +{ + vl_api_registration_t *reg; + u32 context; +} dhcp_client_send_walk_ctx_t; + +static int +send_dhcp_client_entry (const dhcp_client_t * client, void *arg) +{ + dhcp_client_send_walk_ctx_t *ctx; + vl_api_dhcp_client_details_t *mp; + + ctx = arg; + + mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + + mp->_vl_msg_id = ntohs (VL_API_DHCP_CLIENT_DETAILS); + mp->context = ctx->context; + + dhcp_client_data_encode (&mp->client, client); + dhcp_client_lease_encode (&mp->lease, client); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (1); +} + +static void +vl_api_dhcp_client_dump_t_handler (vl_api_dhcp_client_dump_t * mp) +{ + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + dhcp_client_send_walk_ctx_t ctx = { + .reg = reg, + .context = mp->context, + }; + dhcp_client_walk (send_dhcp_client_entry, &ctx); +} + /* * dhcp_api_hookup * Add vpe's API message handlers to the table. - * vlib has alread mapped shared memory and + * vlib has already mapped shared memory and * added the client registration handlers. * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() */ @@ -252,6 +401,11 @@ dhcp_api_hookup (vlib_main_t * vm) */ setup_message_id_table (am); + dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index, + DHCP6_PD_DP_REPLY_REPORT); + dhcp6_set_publisher_node (dhcp6_reply_process_node.index, + DHCP6_DP_REPLY_REPORT); + return 0; }