X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vpp%2Fvpp-api%2Fapi.c;h=330b9159e19401fd1a1b8c770fec71a3ad9108e6;hb=ed1c1835043a1d266a5928c40f41b340f6c968d7;hp=cc067402d185bc7c6d9d4a1a3107f72b3d7984f6;hpb=924d03a97b67c8172c38840558bba52ff1256ddd;p=vpp.git diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index cc067402d18..330b9159e19 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -89,6 +89,7 @@ #include #include #include +#include #undef BIHASH_TYPE #undef __included_bihash_template_h__ @@ -110,6 +111,7 @@ #include #include #include +#include #include #include @@ -117,6 +119,7 @@ #include #include #include +#include #define f64_endian(a) #define f64_print(a,b) @@ -443,6 +446,8 @@ _(SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream) \ _(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \ _(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \ _(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \ +_(SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable) \ +_(SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump) \ _(GET_NEXT_INDEX, get_next_index) \ _(PG_CREATE_INTERFACE, pg_create_interface) \ _(PG_CAPTURE, pg_capture) \ @@ -457,7 +462,13 @@ _(DELETE_SUBIF, delete_subif) \ _(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \ _(PUNT, punt) \ _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \ -_(FLOW_CLASSIFY_DUMP, flow_classify_dump) +_(FLOW_CLASSIFY_DUMP, flow_classify_dump) \ +_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ +_(IP_FIB_DUMP, ip_fib_dump) \ +_(IP_FIB_DETAILS, ip_fib_details) \ +_(IP6_FIB_DUMP, ip6_fib_dump) \ +_(IP6_FIB_DETAILS, ip6_fib_details) \ +_(FEATURE_ENABLE_DISABLE, feature_enable_disable) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -1032,6 +1043,8 @@ static int add_del_route_t_handler (u8 is_multipath, u8 is_add, u8 is_drop, + u8 is_unreach, + u8 is_prohibit, u8 is_local, u8 is_classify, u32 classify_table_index, @@ -1090,22 +1103,29 @@ add_del_route_t_handler (u8 is_multipath, dslock (sm, 1 /* release hint */ , 2 /* tag */ ); - if (is_drop || is_local || is_classify) + if (is_drop || is_local || is_classify || is_unreach || is_prohibit) { /* * special route types that link directly to the adj */ if (is_add) { - dpo_id_t dpo = DPO_NULL; + dpo_id_t dpo = DPO_INVALID; dpo_proto_t dproto; dproto = fib_proto_to_dpo (prefix->fp_proto); if (is_drop) - dpo_copy (&dpo, drop_dpo_get (dproto)); + ip_null_dpo_add_and_lock (dproto, IP_NULL_ACTION_NONE, &dpo); else if (is_local) receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo); + else if (is_unreach) + ip_null_dpo_add_and_lock (dproto, + IP_NULL_ACTION_SEND_ICMP_UNREACH, &dpo); + else if (is_prohibit) + ip_null_dpo_add_and_lock (dproto, + IP_NULL_ACTION_SEND_ICMP_PROHIBIT, + &dpo); else if (is_classify) { if (pool_is_free_index (cm->tables, @@ -1116,7 +1136,7 @@ add_del_route_t_handler (u8 is_multipath, } dpo_set (&dpo, DPO_CLASSIFY, dproto, - classify_dpo_create (prefix->fp_proto, + classify_dpo_create (dproto, ntohl (classify_table_index))); } else @@ -1125,10 +1145,10 @@ add_del_route_t_handler (u8 is_multipath, return VNET_API_ERROR_NO_SUCH_TABLE; } - fib_table_entry_special_dpo_add (fib_index, - prefix, - FIB_SOURCE_API, - FIB_ENTRY_FLAG_EXCLUSIVE, &dpo); + fib_table_entry_special_dpo_update (fib_index, + prefix, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_EXCLUSIVE, &dpo); dpo_reset (&dpo); } else @@ -1255,7 +1275,17 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) memset (&nh, 0, sizeof (nh)); memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4)); - return (add_del_route_t_handler (mp->is_multipath, mp->is_add, mp->is_drop, mp->is_local, mp->is_classify, mp->classify_table_index, mp->is_resolve_host, mp->is_resolve_attached, fib_index, &pfx, 1, // is_ip4 + return (add_del_route_t_handler (mp->is_multipath, + mp->is_add, + mp->is_drop, + mp->is_unreach, + mp->is_prohibit, + mp->is_local, + mp->is_classify, + mp->classify_table_index, + mp->is_resolve_host, + mp->is_resolve_attached, + fib_index, &pfx, 1, &nh, ntohl (mp->next_hop_sw_if_index), next_hop_fib_index, @@ -1290,7 +1320,17 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) memset (&nh, 0, sizeof (nh)); memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6)); - return (add_del_route_t_handler (mp->is_multipath, mp->is_add, mp->is_drop, mp->is_local, mp->is_classify, mp->classify_table_index, mp->is_resolve_host, mp->is_resolve_attached, fib_index, &pfx, 0, // is_ip4 + return (add_del_route_t_handler (mp->is_multipath, + mp->is_add, + mp->is_drop, + mp->is_unreach, + mp->is_prohibit, + mp->is_local, + mp->is_classify, + mp->classify_table_index, + mp->is_resolve_host, + mp->is_resolve_attached, + fib_index, &pfx, 0, &nh, ntohl (mp->next_hop_sw_if_index), next_hop_fib_index, mp->next_hop_weight, @@ -1347,6 +1387,8 @@ mpls_route_add_del_t_handler (vnet_main_t * vnm, memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6)); return (add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add, 0, // mp->is_drop, + 0, // mp->is_unreach, + 0, // mp->is_prohibit, 0, // mp->is_local, mp->mr_is_classify, mp->mr_classify_table_index, @@ -1538,79 +1580,21 @@ vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp) static void vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp) { - vlib_main_t *vm = vlib_get_main (); - ip4_main_t *im4 = &ip4_main; - ip6_main_t *im6 = &ip6_main; vl_api_sw_interface_set_vpath_reply_t *rmp; int rv = 0; - u32 ci; u32 sw_if_index = ntohl (mp->sw_if_index); - ip4_main_t *ip4m = &ip4_main; - ip6_main_t *ip6m = &ip6_main; - ip_lookup_main_t *ip4lm = &ip4m->lookup_main; - ip_lookup_main_t *ip6lm = &ip6m->lookup_main; - ip_config_main_t *rx_cm4u = - &ip4lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT]; - ip_config_main_t *rx_cm4m = - &ip4lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT]; - ip_config_main_t *rx_cm6u = - &ip6lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT]; - ip_config_main_t *rx_cm6m = - &ip6lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT]; VALIDATE_SW_IF_INDEX (mp); l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable); - if (mp->enable) - { - ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast - ci = vnet_config_add_feature (vm, &rx_cm4u->config_main, - ci, - im4->ip4_unicast_rx_feature_vpath, 0, 0); - rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast - ci = vnet_config_add_feature (vm, &rx_cm4m->config_main, - ci, - im4->ip4_multicast_rx_feature_vpath, - 0, 0); - rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast - ci = vnet_config_add_feature (vm, &rx_cm6u->config_main, - ci, - im6->ip6_unicast_rx_feature_vpath, 0, 0); - rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast - ci = vnet_config_add_feature (vm, &rx_cm6m->config_main, - ci, - im6->ip6_multicast_rx_feature_vpath, - 0, 0); - rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci; - } - else - { - ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast - ci = vnet_config_del_feature (vm, &rx_cm4u->config_main, - ci, - im4->ip4_unicast_rx_feature_vpath, 0, 0); - rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast - ci = vnet_config_del_feature (vm, &rx_cm4m->config_main, - ci, - im4->ip4_multicast_rx_feature_vpath, - 0, 0); - rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast - ci = vnet_config_del_feature (vm, &rx_cm6u->config_main, - ci, - im6->ip6_unicast_rx_feature_vpath, 0, 0); - rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci; - ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast - ci = vnet_config_del_feature (vm, &rx_cm6m->config_main, - ci, - im6->ip6_multicast_rx_feature_vpath, - 0, 0); - rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci; - } + vnet_feature_enable_disable ("ip4-unicast", "vpath-input-ip4", + sw_if_index, mp->enable, 0, 0); + vnet_feature_enable_disable ("ip4-multicast", "vpath-input-ip4", + sw_if_index, mp->enable, 0, 0); + vnet_feature_enable_disable ("ip6-unicast", "vpath-input-ip6", + sw_if_index, mp->enable, 0, 0); + vnet_feature_enable_disable ("ip6-multicast", "vpath-input-ip6", + sw_if_index, mp->enable, 0, 0); BAD_SW_IF_INDEX_LABEL; @@ -3284,16 +3268,12 @@ dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp) vl_api_dhcp_proxy_config_reply_t *rmp; int rv = -1; -#if 0 // $$$$ FIXME rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *) (&mp->dhcp_server), (ip6_address_t *) (&mp->dhcp_src_address), (u32) ntohl (mp->rx_vrf_id), (u32) ntohl (mp->server_vrf_id), (int) mp->insert_circuit_id, (int) (mp->is_add == 0)); -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY); } @@ -3944,7 +3924,9 @@ _(memory_size) \ _(skip_n_vectors) \ _(match_n_vectors) \ _(next_table_index) \ -_(miss_next_index) +_(miss_next_index) \ +_(current_data_flag) \ +_(current_data_offset) static void vl_api_classify_add_del_table_t_handler (vl_api_classify_add_del_table_t * mp) @@ -3963,17 +3945,25 @@ static void vl_api_classify_add_del_table_t_handler #undef _ /* The underlying API fails silently, on purpose, so check here */ - if (mp->is_add == 0) - if (pool_is_free_index (cm->tables, table_index)) - { - rv = VNET_API_ERROR_NO_SUCH_TABLE; - goto out; - } + if (mp->is_add == 0) /* delete */ + { + if (pool_is_free_index (cm->tables, table_index)) + { + rv = VNET_API_ERROR_NO_SUCH_TABLE; + goto out; + } + } + else /* add or update */ + { + if (table_index != ~0 && pool_is_free_index (cm->tables, table_index)) + table_index = ~0; + } rv = vnet_classify_add_del_table (cm, mp->mask, nbuckets, memory_size, skip_n_vectors, match_n_vectors, - next_table_index, miss_next_index, &table_index, mp->is_add); + next_table_index, miss_next_index, &table_index, + current_data_flag, current_data_offset, mp->is_add); out: /* *INDENT-OFF* */ @@ -4002,17 +3992,20 @@ static void vl_api_classify_add_del_session_t_handler vnet_classify_main_t *cm = &vnet_classify_main; vl_api_classify_add_del_session_reply_t *rmp; int rv; - u32 table_index, hit_next_index, opaque_index; + u32 table_index, hit_next_index, opaque_index, metadata; i32 advance; + u8 action; table_index = ntohl (mp->table_index); hit_next_index = ntohl (mp->hit_next_index); opaque_index = ntohl (mp->opaque_index); advance = ntohl (mp->advance); + action = mp->action; + metadata = ntohl (mp->metadata); rv = vnet_classify_add_del_session (cm, table_index, mp->match, hit_next_index, opaque_index, - advance, mp->is_add); + advance, action, metadata, mp->is_add); REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY); } @@ -4168,15 +4161,10 @@ vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t * mp) vnet_main_t *vnm = vnet_get_main (); vlib_main_t *vm = vlib_get_main (); -#if DPDK > 0 && DPDK_VHOST_USER - rv = dpdk_vhost_user_create_if ( -#else - rv = vhost_user_create_if ( -#endif - vnm, vm, (char *) mp->sock_filename, - mp->is_server, &sw_if_index, (u64) ~ 0, - mp->renumber, ntohl (mp->custom_dev_instance), - (mp->use_custom_mac) ? mp->mac_address : NULL); + rv = vhost_user_create_if (vnm, vm, (char *) mp->sock_filename, + mp->is_server, &sw_if_index, (u64) ~ 0, + mp->renumber, ntohl (mp->custom_dev_instance), + (mp->use_custom_mac) ? mp->mac_address : NULL); /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY, @@ -4196,14 +4184,9 @@ vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t * mp) vnet_main_t *vnm = vnet_get_main (); vlib_main_t *vm = vlib_get_main (); -#if DPDK > 0 && DPDK_VHOST_USER - rv = dpdk_vhost_user_modify_if ( -#else - rv = vhost_user_modify_if ( -#endif - vnm, vm, (char *) mp->sock_filename, - mp->is_server, sw_if_index, (u64) ~ 0, - mp->renumber, ntohl (mp->custom_dev_instance)); + rv = vhost_user_modify_if (vnm, vm, (char *) mp->sock_filename, + mp->is_server, sw_if_index, (u64) ~ 0, + mp->renumber, ntohl (mp->custom_dev_instance)); REPLY_MACRO (VL_API_MODIFY_VHOST_USER_IF_REPLY); } @@ -4218,11 +4201,7 @@ vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t * mp) vnet_main_t *vnm = vnet_get_main (); vlib_main_t *vm = vlib_get_main (); -#if DPDK > 0 && DPDK_VHOST_USER - rv = dpdk_vhost_user_delete_if (vnm, vm, sw_if_index); -#else rv = vhost_user_delete_if (vnm, vm, sw_if_index); -#endif REPLY_MACRO (VL_API_DELETE_VHOST_USER_IF_REPLY); if (!rv) @@ -4286,11 +4265,7 @@ static void if (q == 0) return; -#if DPDK > 0 && DPDK_VHOST_USER - rv = dpdk_vhost_user_dump_ifs (vnm, vm, &ifaces); -#else rv = vhost_user_dump_ifs (vnm, vm, &ifaces); -#endif if (rv) return; @@ -4354,7 +4329,7 @@ send_ip_address_details (vpe_api_main_t * am, else { u32 *tp = (u32 *) mp->ip; - *tp = ntohl (*(u32 *) ip); + *tp = *(u32 *) ip; } mp->prefix_length = prefix_length; mp->context = context; @@ -4910,7 +4885,7 @@ static void send_vxlan_tunnel_details vl_api_vxlan_tunnel_details_t *rmp; ip4_main_t *im4 = &ip4_main; ip6_main_t *im6 = &ip6_main; - u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4); + u8 is_ipv6 = !ip46_address_is_ip4 (&t->dst); rmp = vl_msg_api_alloc (sizeof (*rmp)); memset (rmp, 0, sizeof (*rmp)); @@ -4928,7 +4903,8 @@ static void send_vxlan_tunnel_details rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id); } rmp->vni = htonl (t->vni); - rmp->decap_next_index = htonl (t->decap_next_index); + /* decap_next_index is deprecated, hard code to l2-input */ + rmp->decap_next_index = htonl (VXLAN_INPUT_NEXT_L2_INPUT); rmp->sw_if_index = htonl (t->sw_if_index); rmp->is_ipv6 = is_ipv6; rmp->context = context; @@ -7219,7 +7195,8 @@ vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp) /* Ignoring the profile id as currently a single profile * is supported */ - error = ip6_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc); + error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable, + mp->seqno, mp->analyse); if (error) { clib_error_report (error); @@ -7618,14 +7595,60 @@ vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp) clib_warning ("BUG"); } +static void +vl_api_mpls_fib_details_t_endian (vl_api_mpls_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +vl_api_mpls_fib_details_t_print (vl_api_mpls_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + + +static void +copy_fib_next_hop (fib_route_path_encode_t * api_rpath, + vl_api_fib_path_t * fp) +{ + int is_ip4; + + if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4) + fp->afi = IP46_TYPE_IP4; + else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6) + fp->afi = IP46_TYPE_IP6; + else + { + is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr); + if (is_ip4) + fp->afi = IP46_TYPE_IP4; + else + fp->afi = IP46_TYPE_IP6; + } + if (fp->afi == IP46_TYPE_IP4) + memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4, + sizeof (api_rpath->rpath.frp_addr.ip4)); + else + memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6, + sizeof (api_rpath->rpath.frp_addr.ip6)); +} + static void send_mpls_fib_details (vpe_api_main_t * am, unix_shared_memory_queue_t * q, - u32 table_id, u32 label, u32 eos, u32 context) + u32 table_id, u32 label, u32 eos, + fib_route_path_encode_t * api_rpaths, u32 context) { vl_api_mpls_fib_details_t *mp; + fib_route_path_encode_t *api_rpath; + vl_api_fib_path_t *fp; + int path_count; - mp = vl_msg_api_alloc (sizeof (*mp)); + path_count = vec_len (api_rpaths); + mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp)); + if (!mp) + return; memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DETAILS); mp->context = context; @@ -7634,6 +7657,17 @@ send_mpls_fib_details (vpe_api_main_t * am, mp->eos_bit = eos; mp->label = htonl (label); + mp->count = htonl (path_count); + fp = mp->path; + vec_foreach (api_rpath, api_rpaths) + { + memset (fp, 0, sizeof (*fp)); + fp->weight = htonl (api_rpath->rpath.frp_weight); + fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index); + copy_fib_next_hop (api_rpath, fp); + fp++; + } + vl_msg_api_send_shmem (q, (u8 *) & mp); } @@ -7648,6 +7682,7 @@ vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp) mpls_label_t key; fib_prefix_t pfx; u32 fib_index; + fib_route_path_encode_t *api_rpaths; q = vl_api_client_index_to_input_queue (mp->client_index); if (q == 0) @@ -7667,19 +7702,309 @@ vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp) { fib_entry_get_prefix(*lfeip, &pfx); fib_index = fib_entry_get_fib_index(*lfeip); - fib_table = fib_table_get(fib_index, pfx.fp_proto); - + api_rpaths = NULL; + fib_entry_encode(*lfeip, &api_rpaths); send_mpls_fib_details (am, q, fib_table->ft_table_id, pfx.fp_label, pfx.fp_eos, + api_rpaths, mp->context); + vec_free(api_rpaths); } vec_free (lfeis); } +static void +vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +vl_api_ip_fib_details_t_endian (vl_api_ip_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +vl_api_ip_fib_details_t_print (vl_api_ip_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +send_ip_fib_details (vpe_api_main_t * am, + unix_shared_memory_queue_t * q, + u32 table_id, fib_prefix_t *pfx, + fib_route_path_encode_t *api_rpaths, u32 context) +{ + vl_api_ip_fib_details_t *mp; + fib_route_path_encode_t *api_rpath; + vl_api_fib_path_t *fp; + int path_count; + + path_count = vec_len(api_rpaths); + mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp)); + if (!mp) + return; + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS); + mp->context = context; + + mp->table_id = htonl (table_id); + mp->address_length = pfx->fp_len; + memcpy(mp->address, &pfx->fp_addr.ip4, sizeof(pfx->fp_addr.ip4)); + + mp->count = htonl (path_count); + fp = mp->path; + vec_foreach(api_rpath, api_rpaths) + { + memset (fp, 0, sizeof (*fp)); + switch (api_rpath->dpo.dpoi_type) + { + case DPO_RECEIVE: + fp->is_local = true; + break; + case DPO_DROP: + fp->is_drop = true; + break; + case DPO_IP_NULL: + switch (api_rpath->dpo.dpoi_index) + { + case IP_NULL_ACTION_NONE: + fp->is_drop = true; + break; + case IP_NULL_ACTION_SEND_ICMP_UNREACH: + fp->is_unreach = true; + break; + case IP_NULL_ACTION_SEND_ICMP_PROHIBIT: + fp->is_prohibit = true; + break; + default: + break; + } + break; + default: + break; + } + fp->weight = htonl(api_rpath->rpath.frp_weight); + fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index); + copy_fib_next_hop (api_rpath, fp); + fp++; + } + + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +static void +vl_api_ip_fib_dump_t_handler (vl_api_ip_fib_dump_t * mp) +{ + vpe_api_main_t *am = &vpe_api_main; + unix_shared_memory_queue_t *q; + ip4_main_t *im = &ip4_main; + fib_table_t *fib_table; + fib_node_index_t lfei, *lfeip, *lfeis = NULL; + mpls_label_t key; + fib_prefix_t pfx; + u32 fib_index; + fib_route_path_encode_t *api_rpaths; + int i; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + /* *INDENT-OFF* */ + pool_foreach (fib_table, im->fibs, + ({ + for (i = 0; i < ARRAY_LEN (fib_table->v4.fib_entry_by_dst_address); i++) + { + hash_foreach(key, lfei, fib_table->v4.fib_entry_by_dst_address[i], + ({ + vec_add1(lfeis, lfei); + })); + } + })); + + vec_sort_with_function(lfeis, fib_entry_cmp_for_sort); + + vec_foreach(lfeip, lfeis) + { + fib_entry_get_prefix(*lfeip, &pfx); + fib_index = fib_entry_get_fib_index(*lfeip); + fib_table = fib_table_get(fib_index, pfx.fp_proto); + api_rpaths = NULL; + fib_entry_encode(*lfeip, &api_rpaths); + send_ip_fib_details (am, q, + fib_table->ft_table_id, + &pfx, + api_rpaths, + mp->context); + vec_free(api_rpaths); + } + + vec_free (lfeis); +} + +static void +vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +vl_api_ip6_fib_details_t_endian (vl_api_ip6_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +vl_api_ip6_fib_details_t_print (vl_api_ip6_fib_details_t * mp) +{ + clib_warning ("BUG"); +} + +static void +send_ip6_fib_details (vpe_api_main_t * am, + unix_shared_memory_queue_t * q, + u32 table_id, fib_prefix_t *pfx, + fib_route_path_encode_t *api_rpaths, u32 context) +{ + vl_api_ip6_fib_details_t *mp; + fib_route_path_encode_t *api_rpath; + vl_api_fib_path_t *fp; + int path_count; + + path_count = vec_len(api_rpaths); + mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp)); + if (!mp) + return; + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS); + mp->context = context; + + mp->table_id = htonl (table_id); + mp->address_length = pfx->fp_len; + memcpy(mp->address, &pfx->fp_addr.ip6, sizeof(pfx->fp_addr.ip6)); + + mp->count = htonl (path_count); + fp = mp->path; + vec_foreach(api_rpath, api_rpaths) + { + memset (fp, 0, sizeof (*fp)); + switch (api_rpath->dpo.dpoi_type) + { + case DPO_RECEIVE: + fp->is_local = true; + break; + case DPO_DROP: + fp->is_drop = true; + break; + case DPO_IP_NULL: + switch (api_rpath->dpo.dpoi_index) + { + case IP_NULL_DPO_ACTION_NUM+IP_NULL_ACTION_NONE: + fp->is_drop = true; + break; + case IP_NULL_DPO_ACTION_NUM+IP_NULL_ACTION_SEND_ICMP_UNREACH: + fp->is_unreach = true; + break; + case IP_NULL_DPO_ACTION_NUM+IP_NULL_ACTION_SEND_ICMP_PROHIBIT: + fp->is_prohibit = true; + break; + default: + break; + } + break; + default: + break; + } + fp->weight = htonl(api_rpath->rpath.frp_weight); + fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index); + copy_fib_next_hop (api_rpath, fp); + fp++; + } + + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +typedef struct apt_ip6_fib_show_ctx_t_ { + u32 fib_index; + fib_node_index_t *entries; +} api_ip6_fib_show_ctx_t; + +static void +api_ip6_fib_table_put_entries (clib_bihash_kv_24_8_t * kvp, + void *arg) +{ + api_ip6_fib_show_ctx_t *ctx = arg; + + if ((kvp->key[2] >> 32) == ctx->fib_index) + { + vec_add1(ctx->entries, kvp->value); + } +} + +static void +api_ip6_fib_table_get_all (unix_shared_memory_queue_t *q, + vl_api_ip6_fib_dump_t *mp, + fib_table_t *fib_table) +{ + vpe_api_main_t *am = &vpe_api_main; + ip6_main_t *im6 = &ip6_main; + ip6_fib_t *fib = &fib_table->v6; + fib_node_index_t *fib_entry_index; + api_ip6_fib_show_ctx_t ctx = { + .fib_index = fib->index, + .entries = NULL, + }; + fib_route_path_encode_t *api_rpaths; + fib_prefix_t pfx; + + BV(clib_bihash_foreach_key_value_pair) + ((BVT(clib_bihash) *) &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash, + api_ip6_fib_table_put_entries, + &ctx); + + vec_sort_with_function(ctx.entries, fib_entry_cmp_for_sort); + + vec_foreach(fib_entry_index, ctx.entries) + { + fib_entry_get_prefix(*fib_entry_index, &pfx); + api_rpaths = NULL; + fib_entry_encode(*fib_entry_index, &api_rpaths); + send_ip6_fib_details (am, q, + fib_table->ft_table_id, + &pfx, + api_rpaths, + mp->context); + vec_free(api_rpaths); + } + + vec_free(ctx.entries); +} + +static void +vl_api_ip6_fib_dump_t_handler (vl_api_ip6_fib_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + ip6_main_t *im6 = &ip6_main; + fib_table_t *fib_table; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + /* *INDENT-OFF* */ + pool_foreach (fib_table, im6->fibs, + ({ + api_ip6_fib_table_get_all(q, mp, fib_table); + })); +} + static void vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp) { @@ -8278,6 +8603,52 @@ static void send_ipfix_classify_table_details (i, q, mp->context); } +static void + vl_api_sw_interface_span_enable_disable_t_handler + (vl_api_sw_interface_span_enable_disable_t * mp) +{ + vl_api_sw_interface_span_enable_disable_reply_t *rmp; + int rv; + + vlib_main_t *vm = vlib_get_main (); + + rv = span_add_delete_entry (vm, ntohl (mp->sw_if_index_from), + ntohl (mp->sw_if_index_to), mp->enable); + + REPLY_MACRO (VL_API_SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY); +} + +static void +vl_api_sw_interface_span_dump_t_handler (vl_api_sw_interface_span_dump_t * mp) +{ + + unix_shared_memory_queue_t *q; + vl_api_sw_interface_span_details_t *rmp; + span_main_t *sm = &span_main; + u32 src_sw_if_index = 0, *dst_sw_if_index; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (!q) + return; + + vec_foreach (dst_sw_if_index, sm->dst_by_src_sw_if_index) + { + if (*dst_sw_if_index > 0) + { + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SPAN_DETAILS); + rmp->context = mp->context; + + rmp->sw_if_index_from = htonl (src_sw_if_index); + rmp->sw_if_index_to = htonl (*dst_sw_if_index); + + vl_msg_api_send_shmem (q, (u8 *) & rmp); + } + src_sw_if_index++; + } +} + static void vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp) { @@ -8732,6 +9103,122 @@ vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp) } } +static void +send_ipsec_spd_details (ipsec_policy_t * p, unix_shared_memory_queue_t * q, + u32 context) +{ + vl_api_ipsec_spd_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS); + mp->context = context; + + mp->spd_id = htonl (p->id); + mp->priority = htonl (p->priority); + mp->is_outbound = p->is_outbound; + mp->is_ipv6 = p->is_ipv6; + if (p->is_ipv6) + { + memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16); + memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16); + memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16); + memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16); + } + else + { + memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4); + memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4); + memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4); + memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4); + } + mp->local_start_port = htons (p->lport.start); + mp->local_stop_port = htons (p->lport.stop); + mp->remote_start_port = htons (p->rport.start); + mp->remote_stop_port = htons (p->rport.stop); + mp->protocol = p->protocol; + mp->policy = p->policy; + mp->sa_id = htonl (p->sa_id); + mp->bytes = clib_host_to_net_u64 (p->counter.bytes); + mp->packets = clib_host_to_net_u64 (p->counter.packets); + + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +static void +vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + ipsec_main_t *im = &ipsec_main; + ipsec_policy_t *policy; + ipsec_spd_t *spd; + uword *p; + u32 spd_index; +#if IPSEC > 0 + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id)); + if (!p) + return; + + spd_index = p[0]; + spd = pool_elt_at_index (im->spds, spd_index); + + pool_foreach (policy, spd->policies, ( + { + if (mp->sa_id == ~(0) + || ntohl (mp->sa_id) == + policy->sa_id) + send_ipsec_spd_details (policy, q, + mp->context);} + )); +#else + clib_warning ("unimplemented"); +#endif +} + +static void +vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp) +{ + vl_api_feature_enable_disable_reply_t *rmp; + int rv = 0; + + u8 *arc_name = format (0, "%s%c", mp->arc_name, 0); + u8 *feature_name = format (0, "%s%c", mp->feature_name, 0); + + vnet_feature_registration_t *reg; + reg = + vnet_get_feature_reg ((const char *) arc_name, + (const char *) feature_name); + if (reg == 0) + rv = VNET_API_ERROR_INVALID_VALUE; + else + { + u32 sw_if_index; + clib_error_t *error = 0; + + sw_if_index = ntohl (mp->sw_if_index); + if (reg->enable_disable_cb) + error = reg->enable_disable_cb (sw_if_index, mp->enable); + if (!error) + vnet_feature_enable_disable ((const char *) arc_name, + (const char *) feature_name, + sw_if_index, mp->enable, 0, 0); + else + { + clib_error_report (error); + rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE; + } + } + + vec_free (feature_name); + vec_free (arc_name); + + REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY); +} + #define BOUNCE_HANDLER(nn) \ static void vl_api_##nn##_t_handler ( \ vl_api_##nn##_t *mp) \ @@ -8762,6 +9249,8 @@ static void vl_api_##nn##_t_handler ( \ vl_msg_api_free (mp); \ } +static void setup_message_id_table (api_main_t * am); + /* * vpe_api_hookup * Add vpe's API message handlers to the table. @@ -8769,7 +9258,6 @@ static void vl_api_##nn##_t_handler ( \ * added the client registration handlers. * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process() */ - static clib_error_t * vpe_api_hookup (vlib_main_t * vm) { @@ -8823,6 +9311,11 @@ vpe_api_hookup (vlib_main_t * vm) am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1; am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1; + /* + * Set up the (msg_name, crc, message-id) table + */ + setup_message_id_table (am); + return 0; } @@ -8976,24 +9469,6 @@ get_unformat_vnet_sw_interface (void) return (void *) &unformat_vnet_sw_interface; } -#undef vl_api_version -#define vl_api_version(n,v) static u32 vpe_api_version = v; -#include -#undef vl_api_version - -int -vl_msg_api_version_check (vl_api_memclnt_create_t * mp) -{ - if (clib_host_to_net_u32 (mp->api_versions[0]) != vpe_api_version) - { - clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x", - clib_host_to_net_u32 (mp->api_versions[0]), - vpe_api_version); - return -1; - } - return 0; -} - static u8 * format_arp_event (u8 * s, va_list * args) { @@ -9057,6 +9532,20 @@ VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = { }; /* *INDENT-ON* */ +#define vl_msg_name_crc_list +#include +#undef vl_msg_name_crc_list + +static void +setup_message_id_table (api_main_t * am) +{ +#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); + foreach_vl_msg_name_crc_memclnt; + foreach_vl_msg_name_crc_vpe; +#undef _ +} + + /* * fd.io coding-style-patch-verification: ON *