From 01b071222d99bea31e2846e95963c475262dd114 Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 2 Nov 2016 10:40:09 -0700 Subject: Dump routes (VPP-500) Change-Id: I86e7382395a8b6471a0deaf57163718d41b71b83 Signed-off-by: Steven --- vpp/vpp-api/api.c | 371 +++++++++++++++++++++++++++++++++++++++++++++- vpp/vpp-api/custom_dump.c | 24 ++- vpp/vpp-api/vpe.api | 80 +++++++++- 3 files changed, 468 insertions(+), 7 deletions(-) (limited to 'vpp') diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index ea7b2a1d..ff0e9e82 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -459,7 +459,11 @@ _(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) \ -_(IPSEC_SPD_DUMP, ipsec_spd_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) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -7573,14 +7577,33 @@ 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 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 is_ip4, 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; @@ -7589,6 +7612,29 @@ 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); + memcpy (fp->next_hop, &api_rpath->rpath.frp_addr, sizeof (fp->next_hop)); + 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; + } + fp++; + } + vl_msg_api_send_shmem (q, (u8 *) & mp); } @@ -7603,6 +7649,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) @@ -7622,19 +7669,333 @@ 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 is_ip4, 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); + memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop)); + 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; + } + 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 is_ip4, 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); + memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop)); + 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; + } + 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) { diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c index 45d7b96a..220ba988 100644 --- a/vpp/vpp-api/custom_dump.c +++ b/vpp/vpp-api/custom_dump.c @@ -2056,6 +2056,26 @@ static void *vl_api_mpls_fib_dump_t_print FINISH; } +static void *vl_api_ip_fib_dump_t_print + (vl_api_ip_fib_dump_t * mp, void *handle) +{ + u8 *s; + + s = format (0, "SCRIPT: ip_fib_dump "); + + FINISH; +} + +static void *vl_api_ip6_fib_dump_t_print + (vl_api_ip6_fib_dump_t * mp, void *handle) +{ + u8 *s; + + s = format (0, "SCRIPT: ip6_fib_dump "); + + FINISH; +} + static void *vl_api_classify_table_ids_t_print (vl_api_classify_table_ids_t * mp, void *handle) { @@ -3006,7 +3026,9 @@ _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \ _(FLOW_CLASSIFY_DUMP, flow_classify_dump) \ _(GET_FIRST_MSG_ID, get_first_msg_id) \ _(IOAM_ENABLE, ioam_enable) \ -_(IOAM_DISABLE, ioam_disable) +_(IOAM_DISABLE, ioam_disable) \ +_(IP_FIB_DUMP, ip_fib_dump) \ +_(IP6_FIB_DUMP, ip6_fib_dump) void vl_msg_api_custom_dump_configure (api_main_t * am) { diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 67d95034..dc2d4850 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -431,17 +431,95 @@ define mpls_fib_dump u32 context; }; +/** \brief FIB path + @param sw_if_index - index of the interface + @param weight - The weight, for UCMP + @param is_local - local if non-zero, else remote + @param is_drop - Drop the packet + @param is_unreach - Drop the packet and rate limit send ICMP unreachable + @param is_prohibit - Drop the packet and rate limit send ICMP prohibited + @param afi - the afi of the next hop, IP46_TYPE_IP4=1, IP46_TYPE_IP6=2 + @param next_hop[16] - the next hop address +*/ +typeonly manual_print manual_endian define fib_path +{ + u32 sw_if_index; + u32 weight; + u8 is_local; + u8 is_drop; + u8 is_unreach; + u8 is_prohibit; + u8 afi; + u8 next_hop[16]; +}; + /** \brief mpls FIB table response @param table_id - MPLS fib table id @param s_bit - End-of-stack bit @param label - MPLS label value + @param count - the number of fib_path in path + @param path - array of of fib_path structures */ -define mpls_fib_details +manual_endian manual_print define mpls_fib_details { u32 context; u32 table_id; u8 eos_bit; u32 label; + u32 count; + vl_api_fib_path_t path[count]; +}; + +/** \brief Dump IP6 fib table + @param client_index - opaque cookie to identify the sender +*/ +define ip6_fib_dump +{ + u32 client_index; + u32 context; +}; + +/** \brief IP6 FIB table response + @param table_id - IP6 fib table id + @address_length - mask length + @address - ip6 prefix + @param count - the number of fib_path in path + @param path - array of of fib_path structures +*/ +manual_endian manual_print define ip6_fib_details +{ + u32 context; + u32 table_id; + u8 address_length; + u8 address[16]; + u32 count; + vl_api_fib_path_t path[count]; +}; + +/** \brief Dump IP fib table + @param client_index - opaque cookie to identify the sender +*/ +define ip_fib_dump +{ + u32 client_index; + u32 context; +}; + +/** \brief IP FIB table response + @param table_id - IP fib table id + @address_length - mask length + @address - ip4 prefix + @param count - the number of fib_path in path + @param path - array of of fib_path structures +*/ +manual_endian manual_print define ip_fib_details +{ + u32 context; + u32 table_id; + u8 address_length; + u8 address[4]; + u32 count; + vl_api_fib_path_t path[count]; }; /** \brief Bind/Unbind an MPLS local label to an IP prefix. i.e. create -- cgit 1.2.3-korg