Dump routes (VPP-500) 70/3670/9
authorSteven <sluong@cisco.com>
Wed, 2 Nov 2016 17:40:09 +0000 (10:40 -0700)
committerNeale Ranns <nranns@cisco.com>
Tue, 15 Nov 2016 08:13:26 +0000 (08:13 +0000)
Change-Id: I86e7382395a8b6471a0deaf57163718d41b71b83
Signed-off-by: Steven <sluong@cisco.com>
vnet/vnet/fib/fib_entry.c
vnet/vnet/fib/fib_entry.h
vnet/vnet/fib/fib_path.c
vnet/vnet/fib/fib_path.h
vnet/vnet/fib/fib_types.h
vpp-api-test/vat/api_format.c
vpp-api/python/pneum/api-gen.py
vpp/vpp-api/api.c
vpp/vpp-api/custom_dump.c
vpp/vpp-api/vpe.api
vppapigen/pyvppapigen.py

index 4080b76..da2656e 100644 (file)
@@ -1478,6 +1478,16 @@ fib_entry_module_init (void)
     fib_node_register_type (FIB_NODE_TYPE_ENTRY, &fib_entry_vft);
 }
 
+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)
index 39b2083..d62a940 100644 (file)
@@ -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);
index 9fe653d..9866931 100644 (file)
@@ -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)
 {
index 2c141a4..4151c57 100644 (file)
@@ -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
index 1e70a2a..83123a5 100644 (file)
@@ -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
index 08c1079..5c77590 100644 (file)
@@ -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                                    \
index fcf293e..4456835 100755 (executable)
@@ -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,
index ea7b2a1..ff0e9e8 100644 (file)
@@ -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)
 {
index 45d7b96..220ba98 100644 (file)
@@ -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)
 {
index 67d9503..dc2d485 100644 (file)
@@ -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
index 675712a..ea66951 100755 (executable)
@@ -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