diff options
-rw-r--r-- | vnet/vnet/fib/fib_entry.c | 10 | ||||
-rw-r--r-- | vnet/vnet/fib/fib_entry.h | 2 | ||||
-rw-r--r-- | vnet/vnet/fib/fib_path.c | 43 | ||||
-rw-r--r-- | vnet/vnet/fib/fib_path.h | 5 | ||||
-rw-r--r-- | vnet/vnet/fib/fib_types.h | 9 | ||||
-rw-r--r-- | vpp-api-test/vat/api_format.c | 238 | ||||
-rwxr-xr-x | vpp-api/python/pneum/api-gen.py | 2 | ||||
-rw-r--r-- | vpp/vpp-api/api.c | 371 | ||||
-rw-r--r-- | vpp/vpp-api/custom_dump.c | 24 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 80 | ||||
-rwxr-xr-x | vppapigen/pyvppapigen.py | 2 |
11 files changed, 775 insertions, 11 deletions
diff --git a/vnet/vnet/fib/fib_entry.c b/vnet/vnet/fib/fib_entry.c index 4080b7622d1..da2656e35aa 100644 --- a/vnet/vnet/fib/fib_entry.c +++ b/vnet/vnet/fib/fib_entry.c @@ -1479,6 +1479,16 @@ fib_entry_module_init (void) } void +fib_entry_encode (fib_node_index_t fib_entry_index, + fib_route_path_encode_t **api_rpaths) +{ + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths); +} + +void fib_entry_get_prefix (fib_node_index_t fib_entry_index, fib_prefix_t *pfx) { diff --git a/vnet/vnet/fib/fib_entry.h b/vnet/vnet/fib/fib_entry.h index 39b2083ea9a..d62a94043b3 100644 --- a/vnet/vnet/fib/fib_entry.h +++ b/vnet/vnet/fib/fib_entry.h @@ -497,6 +497,8 @@ extern u32 fib_entry_get_resolving_interface_for_source( fib_node_index_t fib_entry_index, fib_source_t source); +extern void fib_entry_encode(fib_node_index_t fib_entry_index, + fib_route_path_encode_t **api_rpaths); extern void fib_entry_get_prefix(fib_node_index_t fib_entry_index, fib_prefix_t *pfx); extern u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index); diff --git a/vnet/vnet/fib/fib_path.c b/vnet/vnet/fib/fib_path.c index 9fe653dc8d0..98669317b92 100644 --- a/vnet/vnet/fib/fib_path.c +++ b/vnet/vnet/fib/fib_path.c @@ -1818,6 +1818,49 @@ fib_path_is_looped (fib_node_index_t path_index) return (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RECURSIVE_LOOP); } +int +fib_path_encode (fib_node_index_t path_list_index, + fib_node_index_t path_index, + void *ctx) +{ + fib_route_path_encode_t **api_rpaths = ctx; + fib_route_path_encode_t *api_rpath; + fib_path_t *path; + + path = fib_path_get(path_index); + if (!path) + return (0); + vec_add2(*api_rpaths, api_rpath, 1); + api_rpath->rpath.frp_weight = path->fp_weight; + api_rpath->rpath.frp_proto = path->fp_nh_proto; + api_rpath->rpath.frp_sw_if_index = ~0; + api_rpath->dpo = path->exclusive.fp_ex_dpo; + switch (path->fp_type) + { + case FIB_PATH_TYPE_RECEIVE: + api_rpath->rpath.frp_addr = path->receive.fp_addr; + api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface; + break; + case FIB_PATH_TYPE_ATTACHED: + api_rpath->rpath.frp_sw_if_index = path->attached.fp_interface; + break; + case FIB_PATH_TYPE_ATTACHED_NEXT_HOP: + api_rpath->rpath.frp_sw_if_index = path->attached_next_hop.fp_interface; + api_rpath->rpath.frp_addr = path->attached_next_hop.fp_nh; + break; + case FIB_PATH_TYPE_SPECIAL: + break; + case FIB_PATH_TYPE_DEAG: + break; + case FIB_PATH_TYPE_RECURSIVE: + api_rpath->rpath.frp_addr = path->recursive.fp_nh; + break; + default: + break; + } + return (1); +} + void fib_path_module_init (void) { diff --git a/vnet/vnet/fib/fib_path.h b/vnet/vnet/fib/fib_path.h index 2c141a4150d..4151c578aed 100644 --- a/vnet/vnet/fib/fib_path.h +++ b/vnet/vnet/fib/fib_path.h @@ -150,7 +150,8 @@ extern u32 fib_path_get_resolving_interface(fib_node_index_t fib_entry_index); extern int fib_path_get_weight(fib_node_index_t path_index); extern void fib_path_module_init(void); - -extern void fib_path_module_init(void); +extern int fib_path_encode(fib_node_index_t path_list_index, + fib_node_index_t path_index, + void *ctx); #endif diff --git a/vnet/vnet/fib/fib_types.h b/vnet/vnet/fib/fib_types.h index 1e70a2a98d8..83123a5127a 100644 --- a/vnet/vnet/fib/fib_types.h +++ b/vnet/vnet/fib/fib_types.h @@ -316,4 +316,13 @@ typedef struct fib_route_path_t_ { mpls_label_t frp_label; } fib_route_path_t; +/** + * @brief + * A representation of a fib path for fib_path_encode to convey the information to the caller + */ +typedef struct fib_route_path_encode_t_ { + fib_route_path_t rpath; + dpo_id_t dpo; +} fib_route_path_encode_t; + #endif diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index 08c1079294a..5c77590ce49 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -3811,7 +3811,9 @@ _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply) \ _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details) \ _(DELETE_SUBIF_REPLY, delete_subif_reply) \ _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \ -_(PUNT_REPLY, punt_reply) +_(PUNT_REPLY, punt_reply) \ +_(IP_FIB_DETAILS, ip_fib_details) \ +_(IP6_FIB_DETAILS, ip6_fib_details) /* M: construct, but don't yet send a message */ @@ -14853,21 +14855,43 @@ api_mpls_fib_encap_dump (vat_main_t * vam) W; } +#define vl_api_mpls_fib_details_t_endian vl_noop_handler +#define vl_api_mpls_fib_details_t_print vl_noop_handler + static void vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp) { vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); + vl_api_fib_path_t *fp; + int i; fformat (vam->ofp, "table-id %d, label %u, ess_bit %u\n", ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit); + fp = mp->path; + for (i = 0; i < count; i++) + { + fformat (vam->ofp, + " weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, " + "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight), + ntohl (fp->sw_if_index), fp->is_local, fp->is_drop, + fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address, + fp->next_hop, fp->afi); + fp++; + } } static void vl_api_mpls_fib_details_t_handler_json (vl_api_mpls_fib_details_t * mp) { vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); vat_json_node_t *node = NULL; + struct in_addr ip4; + struct in6_addr ip6; + vl_api_fib_path_t *fp; + int i; if (VAT_JSON_ARRAY != vam->json_tree.type) { @@ -14880,6 +14904,28 @@ static void vl_api_mpls_fib_details_t_handler_json vat_json_object_add_uint (node, "table", ntohl (mp->table_id)); vat_json_object_add_uint (node, "s_bit", mp->eos_bit); vat_json_object_add_uint (node, "label", ntohl (mp->label)); + vat_json_object_add_uint (node, "path_count", count); + fp = mp->path; + for (i = 0; i < count; i++) + { + vat_json_object_add_uint (node, "weight", ntohl (fp->weight)); + vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index)); + vat_json_object_add_uint (node, "is_local", fp->is_local); + vat_json_object_add_uint (node, "is_drop", fp->is_drop); + vat_json_object_add_uint (node, "is_unreach", fp->is_unreach); + vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit); + vat_json_object_add_uint (node, "next_hop_afi", fp->afi); + if (fp->afi == IP46_TYPE_IP4) + { + clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4)); + vat_json_object_add_ip4 (node, "next_hop", ip4); + } + else if (fp->afi == IP46_TYPE_IP6) + { + clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6)); + vat_json_object_add_ip6 (node, "next_hop", ip6); + } + } } static int @@ -14900,6 +14946,192 @@ api_mpls_fib_dump (vat_main_t * vam) W; } +#define vl_api_ip_fib_details_t_endian vl_noop_handler +#define vl_api_ip_fib_details_t_print vl_noop_handler + +static void +vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp) +{ + vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); + vl_api_fib_path_t *fp; + int i; + + fformat (vam->ofp, + "table-id %d, prefix %U/%d\n", + ntohl (mp->table_id), format_ip4_address, mp->address, + mp->address_length); + fp = mp->path; + for (i = 0; i < count; i++) + { + fformat (vam->ofp, + " weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, " + "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight), + ntohl (fp->sw_if_index), fp->is_local, fp->is_drop, + fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address, + fp->next_hop, fp->afi); + fp++; + } +} + +static void vl_api_ip_fib_details_t_handler_json + (vl_api_ip_fib_details_t * mp) +{ + vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); + vat_json_node_t *node = NULL; + struct in_addr ip4; + struct in6_addr ip6; + vl_api_fib_path_t *fp; + int i; + + if (VAT_JSON_ARRAY != vam->json_tree.type) + { + ASSERT (VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array (&vam->json_tree); + } + node = vat_json_array_add (&vam->json_tree); + + vat_json_init_object (node); + vat_json_object_add_uint (node, "table", ntohl (mp->table_id)); + clib_memcpy (&ip4, &mp->address, sizeof (ip4)); + vat_json_object_add_ip4 (node, "prefix", ip4); + vat_json_object_add_uint (node, "mask_length", mp->address_length); + vat_json_object_add_uint (node, "path_count", count); + fp = mp->path; + for (i = 0; i < count; i++) + { + vat_json_object_add_uint (node, "weight", ntohl (fp->weight)); + vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index)); + vat_json_object_add_uint (node, "is_local", fp->is_local); + vat_json_object_add_uint (node, "is_drop", fp->is_drop); + vat_json_object_add_uint (node, "is_unreach", fp->is_unreach); + vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit); + vat_json_object_add_uint (node, "next_hop_afi", fp->afi); + if (fp->afi == IP46_TYPE_IP4) + { + clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4)); + vat_json_object_add_ip4 (node, "next_hop", ip4); + } + else if (fp->afi == IP46_TYPE_IP6) + { + clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6)); + vat_json_object_add_ip6 (node, "next_hop", ip6); + } + } +} + +static int +api_ip_fib_dump (vat_main_t * vam) +{ + vl_api_ip_fib_dump_t *mp; + f64 timeout; + + M (IP_FIB_DUMP, ip_fib_dump); + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t *mp; + M (CONTROL_PING, control_ping); + S; + } + W; +} + +#define vl_api_ip6_fib_details_t_endian vl_noop_handler +#define vl_api_ip6_fib_details_t_print vl_noop_handler + +static void +vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp) +{ + vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); + vl_api_fib_path_t *fp; + int i; + + fformat (vam->ofp, + "table-id %d, prefix %U/%d\n", + ntohl (mp->table_id), format_ip6_address, mp->address, + mp->address_length); + fp = mp->path; + for (i = 0; i < count; i++) + { + fformat (vam->ofp, + " weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, " + "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight), + ntohl (fp->sw_if_index), fp->is_local, fp->is_drop, + fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address, + fp->next_hop, fp->afi); + fp++; + } +} + +static void vl_api_ip6_fib_details_t_handler_json + (vl_api_ip6_fib_details_t * mp) +{ + vat_main_t *vam = &vat_main; + int count = ntohl (mp->count); + vat_json_node_t *node = NULL; + struct in_addr ip4; + struct in6_addr ip6; + vl_api_fib_path_t *fp; + int i; + + if (VAT_JSON_ARRAY != vam->json_tree.type) + { + ASSERT (VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array (&vam->json_tree); + } + node = vat_json_array_add (&vam->json_tree); + + vat_json_init_object (node); + vat_json_object_add_uint (node, "table", ntohl (mp->table_id)); + clib_memcpy (&ip6, &mp->address, sizeof (ip6)); + vat_json_object_add_ip6 (node, "prefix", ip6); + vat_json_object_add_uint (node, "mask_length", mp->address_length); + vat_json_object_add_uint (node, "path_count", count); + fp = mp->path; + for (i = 0; i < count; i++) + { + vat_json_object_add_uint (node, "weight", ntohl (fp->weight)); + vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index)); + vat_json_object_add_uint (node, "is_local", fp->is_local); + vat_json_object_add_uint (node, "is_drop", fp->is_drop); + vat_json_object_add_uint (node, "is_unreach", fp->is_unreach); + vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit); + vat_json_object_add_uint (node, "next_hop_afi", fp->afi); + if (fp->afi == IP46_TYPE_IP4) + { + clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4)); + vat_json_object_add_ip4 (node, "next_hop", ip4); + } + else if (fp->afi == IP46_TYPE_IP6) + { + clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6)); + vat_json_object_add_ip6 (node, "next_hop", ip6); + } + } +} + +static int +api_ip6_fib_dump (vat_main_t * vam) +{ + vl_api_ip6_fib_dump_t *mp; + f64 timeout; + + M (IP6_FIB_DUMP, ip6_fib_dump); + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t *mp; + M (CONTROL_PING, control_ping); + S; + } + W; +} + int api_classify_table_ids (vat_main_t * vam) { @@ -16503,7 +16735,9 @@ _(l2_interface_pbb_tag_rewrite, \ _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]") \ _(flow_classify_set_interface, \ "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \ -_(flow_classify_dump, "type [ip4|ip6]") +_(flow_classify_dump, "type [ip4|ip6]") \ +_(ip_fib_dump, "") \ +_(ip6_fib_dump, "") /* List of command functions, CLI names map directly to functions */ #define foreach_cli_function \ diff --git a/vpp-api/python/pneum/api-gen.py b/vpp-api/python/pneum/api-gen.py index fcf293ecbc0..445683523de 100755 --- a/vpp-api/python/pneum/api-gen.py +++ b/vpp-api/python/pneum/api-gen.py @@ -33,6 +33,7 @@ format_struct = {'u8': 'B', 'i32' : 'i', 'u64' : 'Q', 'f64' : 'd', + 'vl_api_fib_path_t' : 'IIBBBBBBBBBBBBBBBBBBBBB', 'vl_api_ip4_fib_counter_t' : 'IBQQ', 'vl_api_ip6_fib_counter_t' : 'QQBQQ', 'vl_api_lisp_adjacency_t' : 'B' * 35, @@ -46,6 +47,7 @@ type_size = {'u8': 1, 'i32' : 4, 'u64' : 8, 'f64' : 8, + 'vl_api_fib_path_t' : 29, 'vl_api_ip4_fib_counter_t' : 21, 'vl_api_ip6_fib_counter_t' : 33, 'vl_api_lisp_adjacency_t' : 35, diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index ea7b2a1defa..ff0e9e82187 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) @@ -7574,13 +7578,32 @@ vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp) } 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,20 +7669,334 @@ 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) { clib_warning ("BUG"); diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c index 45d7b96a203..220ba988804 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 67d95034bcc..dc2d485056a 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 diff --git a/vppapigen/pyvppapigen.py b/vppapigen/pyvppapigen.py index 675712ab616..ea669517c3e 100755 --- a/vppapigen/pyvppapigen.py +++ b/vppapigen/pyvppapigen.py @@ -34,6 +34,7 @@ format_struct = {'u8': 'B', 'i32' : 'i', 'u64' : 'Q', 'f64' : 'd', + 'vl_api_fib_path_t' : 'IIBBBBBBBBBBBBBBBBBBBBB', 'vl_api_ip4_fib_counter_t' : 'IBQQ', 'vl_api_ip6_fib_counter_t' : 'QQBQQ', 'vl_api_lisp_adjacency_t' : 'B' * 35 @@ -47,6 +48,7 @@ type_size = {'u8': 1, 'i32' : 4, 'u64' : 8, 'f64' : 8, + 'vl_api_fib_path_t' : 29, 'vl_api_ip4_fib_counter_t' : 21, 'vl_api_ip6_fib_counter_t' : 33, 'vl_api_lisp_adjacency_t' : 35 |