summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vnet/vnet/fib/fib_entry.c10
-rw-r--r--vnet/vnet/fib/fib_entry.h2
-rw-r--r--vnet/vnet/fib/fib_path.c43
-rw-r--r--vnet/vnet/fib/fib_path.h5
-rw-r--r--vnet/vnet/fib/fib_types.h9
-rw-r--r--vpp-api-test/vat/api_format.c238
-rwxr-xr-xvpp-api/python/pneum/api-gen.py2
-rw-r--r--vpp/vpp-api/api.c371
-rw-r--r--vpp/vpp-api/custom_dump.c24
-rw-r--r--vpp/vpp-api/vpe.api80
-rwxr-xr-xvppapigen/pyvppapigen.py2
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