FIB: encode the label stack in the FIB path during table dump
Change-Id: I28e8a99b980ad343a4209e673201791b91ceab4e
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/plugins/abf/abf_api.c b/src/plugins/abf/abf_api.c
index 0bf714b..bf25669 100644
--- a/src/plugins/abf/abf_api.c
+++ b/src/plugins/abf/abf_api.c
@@ -185,7 +185,7 @@
mp->policy.acl_index = htonl (ap->ap_acl);
mp->policy.policy_id = htonl (ap->ap_id);
- fib_path_list_walk (ap->ap_pl, fib_path_encode, &api_rpaths);
+ fib_path_list_walk_w_ext (ap->ap_pl, NULL, fib_path_encode, &api_rpaths);
fp = mp->policy.paths;
vec_foreach (api_rpath, api_rpaths)
diff --git a/src/vnet/bier/bier_api.c b/src/vnet/bier/bier_api.c
index ed1e35f..d8248b1 100644
--- a/src/vnet/bier/bier_api.c
+++ b/src/vnet/bier/bier_api.c
@@ -264,7 +264,10 @@
mp->br_bp = htons(be->be_bp);
mp->br_n_paths = htonl(n_paths);
- fib_path_list_walk(be->be_path_list, fib_path_encode, &api_rpaths);
+ fib_path_list_walk_w_ext(be->be_path_list,
+ NULL,
+ fib_path_encode,
+ &api_rpaths);
fp = mp->br_paths;
vec_foreach (api_rpath, api_rpaths)
@@ -625,7 +628,10 @@
mp->bde_payload_proto = pproto;
mp->bde_bp = htons(bp);
- fib_path_list_walk(pl, fib_path_encode, &api_rpaths);
+ fib_path_list_walk_w_ext(pl,
+ NULL,
+ fib_path_encode,
+ &api_rpaths);
fp = mp->bde_paths;
vec_foreach (api_rpath, api_rpaths)
diff --git a/src/vnet/fib/fib_api.c b/src/vnet/fib/fib_api.c
index d46b9e2..98f92c3 100644
--- a/src/vnet/fib/fib_api.c
+++ b/src/vnet/fib/fib_api.c
@@ -17,6 +17,7 @@
#include <vlibmemory/api.h>
#include <vnet/fib/fib_api.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/mfib/mfib_table.h>
#include <vnet/bier/bier_disp_table.h>
#include <vnet/dpo/ip_null_dpo.h>
@@ -207,6 +208,8 @@
fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
vl_api_fib_path_t *out)
{
+ int ii;
+
clib_memset (out, 0, sizeof (*out));
switch (api_rpath->dpo.dpoi_type)
{
@@ -246,12 +249,20 @@
if ((DPO_PROTO_IP6 == api_rpath->rpath.frp_proto) ||
(DPO_PROTO_IP4 == api_rpath->rpath.frp_proto))
{
- fib_table_t *fib;
-
- fib = fib_table_get (api_rpath->rpath.frp_fib_index,
- dpo_proto_to_fib(api_rpath->rpath.frp_proto));
-
- out->table_id = htonl (fib->ft_table_id);
+ if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RPF_ID)
+ {
+ out->table_id =
+ htonl(mfib_table_get_table_id(
+ api_rpath->rpath.frp_fib_index,
+ dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
+ }
+ else
+ {
+ out->table_id =
+ htonl(fib_table_get_table_id(
+ api_rpath->rpath.frp_fib_index,
+ dpo_proto_to_fib(api_rpath->rpath.frp_proto)));
+ }
}
}
@@ -264,6 +275,41 @@
out->is_udp_encap = 1;
out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
}
+ if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_INTF_RX)
+ {
+ out->is_interface_rx = 1;
+ }
+ if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_LOCAL)
+ {
+ out->is_local = 1;
+ }
+ if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_HOST)
+ {
+ out->is_resolve_host = 1;
+ }
+ if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED)
+ {
+ out->is_resolve_attached = 1;
+ }
+ /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_ATTACHED) { */
+ /* out->is_attached = 1; */
+ /* } */
+ /* if (api_rpath->rpath.frp_flags & FIB_ROUTE_PATH_CONNECTED) { */
+ /* out->is_connected = 1; */
+ /* } */
+ if (api_rpath->rpath.frp_label_stack)
+ {
+ for (ii = 0; ii < vec_len(api_rpath->rpath.frp_label_stack); ii++)
+ {
+ out->label_stack[ii].label =
+ htonl(api_rpath->rpath.frp_label_stack[ii].fml_value);
+ out->label_stack[ii].ttl =
+ api_rpath->rpath.frp_label_stack[ii].fml_ttl;
+ out->label_stack[ii].exp =
+ api_rpath->rpath.frp_label_stack[ii].fml_exp;
+ }
+ out->n_labels = ii;
+ }
}
fib_protocol_t
diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c
index eaedc50..32e45f2 100644
--- a/src/vnet/fib/fib_entry.c
+++ b/src/vnet/fib/fib_entry.c
@@ -1652,12 +1652,25 @@
fib_entry_encode (fib_node_index_t fib_entry_index,
fib_route_path_encode_t **api_rpaths)
{
+ fib_path_ext_list_t *ext_list;
fib_entry_t *fib_entry;
+ fib_entry_src_t *bsrc;
+ ext_list = NULL;
fib_entry = fib_entry_get(fib_entry_index);
+ bsrc = fib_entry_get_best_src_i(fib_entry);
+
+ if (bsrc)
+ {
+ ext_list = &bsrc->fes_path_exts;
+ }
+
if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
{
- fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths);
+ fib_path_list_walk_w_ext(fib_entry->fe_parent,
+ ext_list,
+ fib_path_encode,
+ api_rpaths);
}
}
diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c
index f528c67..d4a701d 100644
--- a/src/vnet/fib/fib_path.c
+++ b/src/vnet/fib/fib_path.c
@@ -37,6 +37,7 @@
#include <vnet/fib/fib_internal.h>
#include <vnet/fib/fib_urpf_list.h>
#include <vnet/fib/mpls_fib.h>
+#include <vnet/fib/fib_path_ext.h>
#include <vnet/udp/udp_encap.h>
#include <vnet/bier/bier_fmask.h>
#include <vnet/bier/bier_table.h>
@@ -605,10 +606,14 @@
vnm,
path->dvr.fp_interface));
break;
+ case FIB_PATH_TYPE_DEAG:
+ s = format (s, " %sfib-index:%d",
+ (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ? "m" : ""),
+ path->deag.fp_tbl_id);
+ break;
case FIB_PATH_TYPE_RECEIVE:
case FIB_PATH_TYPE_INTF_RX:
case FIB_PATH_TYPE_SPECIAL:
- case FIB_PATH_TYPE_DEAG:
case FIB_PATH_TYPE_EXCLUSIVE:
if (dpo_id_is_valid(&path->fp_dpo))
{
@@ -2609,7 +2614,8 @@
fib_path_list_walk_rc_t
fib_path_encode (fib_node_index_t path_list_index,
- fib_node_index_t path_index,
+ fib_node_index_t path_index,
+ const fib_path_ext_t *path_ext,
void *ctx)
{
fib_route_path_encode_t **api_rpaths = ctx;
@@ -2628,7 +2634,7 @@
api_rpath->dpo = path->fp_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;
@@ -2647,6 +2653,10 @@
break;
case FIB_PATH_TYPE_DEAG:
api_rpath->rpath.frp_fib_index = path->deag.fp_tbl_id;
+ if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
+ {
+ api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_RPF_ID;
+ }
break;
case FIB_PATH_TYPE_RECURSIVE:
api_rpath->rpath.frp_addr = path->recursive.fp_nh.fp_ip;
@@ -2660,9 +2670,18 @@
api_rpath->rpath.frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
break;
+ case FIB_PATH_TYPE_INTF_RX:
+ api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface;
+ api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_INTF_RX;
+ break;
default:
break;
- }
+ }
+
+ if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS)
+ {
+ api_rpath->rpath.frp_label_stack = path_ext->fpe_path.frp_label_stack;
+ }
return (FIB_PATH_LIST_WALK_CONTINUE);
}
diff --git a/src/vnet/fib/fib_path.h b/src/vnet/fib/fib_path.h
index e162f4d..57dec6d 100644
--- a/src/vnet/fib/fib_path.h
+++ b/src/vnet/fib/fib_path.h
@@ -183,6 +183,7 @@
extern void fib_path_module_init(void);
extern fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index,
fib_node_index_t path_index,
+ const struct fib_path_ext_t_ *ext_list,
void *ctx);
#endif
diff --git a/src/vnet/fib/fib_path_ext.c b/src/vnet/fib/fib_path_ext.c
index 5ecf3a9..209b627 100644
--- a/src/vnet/fib/fib_path_ext.c
+++ b/src/vnet/fib/fib_path_ext.c
@@ -328,11 +328,14 @@
{
fib_path_ext_t *path_ext;
- vec_foreach(path_ext, list->fpel_exts)
+ if (NULL != list)
{
- if (path_ext->fpe_path_index == path_index)
+ vec_foreach(path_ext, list->fpel_exts)
{
- return (path_ext);
+ if (path_ext->fpe_path_index == path_index)
+ {
+ return (path_ext);
+ }
}
}
return (NULL);
diff --git a/src/vnet/fib/fib_path_list.c b/src/vnet/fib/fib_path_list.c
index 568886a..4e110fb 100644
--- a/src/vnet/fib/fib_path_list.c
+++ b/src/vnet/fib/fib_path_list.c
@@ -24,6 +24,7 @@
#include <vnet/fib/fib_node_list.h>
#include <vnet/fib/fib_walk.h>
#include <vnet/fib/fib_urpf_list.h>
+#include <vnet/fib/fib_path_ext.h>
/**
* The magic number of child entries that make a path-list popular.
@@ -722,7 +723,7 @@
if (FIB_NODE_INDEX_INVALID != old_path_list_index)
{
fib_path_list_destroy(path_list);
-
+
path_list_index = old_path_list_index;
}
else
@@ -747,7 +748,7 @@
return (path_list_index);
}
-static fib_path_cfg_flags_t
+static fib_path_cfg_flags_t
fib_path_list_flags_2_path_flags (fib_path_list_flags_t plf)
{
fib_path_cfg_flags_t pf = FIB_PATH_CFG_FLAG_NONE;
@@ -1343,6 +1344,29 @@
}
}
+void
+fib_path_list_walk_w_ext (fib_node_index_t path_list_index,
+ const fib_path_ext_list_t *ext_list,
+ fib_path_list_walk_w_ext_fn_t func,
+ void *ctx)
+{
+ fib_node_index_t *path_index;
+ fib_path_list_t *path_list;
+ fib_path_ext_t *path_ext;
+
+ path_list = fib_path_list_get(path_list_index);
+
+ vec_foreach(path_index, path_list->fpl_paths)
+ {
+ path_ext = fib_path_ext_list_find_by_path_index(ext_list, *path_index);
+
+ if (FIB_PATH_LIST_WALK_STOP == func(path_list_index,
+ *path_index,
+ path_ext,
+ ctx))
+ break;
+ }
+}
void
fib_path_list_module_init (void)
diff --git a/src/vnet/fib/fib_path_list.h b/src/vnet/fib/fib_path_list.h
index 18835a6..380eb1a 100644
--- a/src/vnet/fib/fib_path_list.h
+++ b/src/vnet/fib/fib_path_list.h
@@ -183,6 +183,17 @@
fib_path_list_walk_fn_t func,
void *ctx);
+typedef fib_path_list_walk_rc_t (*fib_path_list_walk_w_ext_fn_t)(
+ fib_node_index_t pl_index,
+ fib_node_index_t path_index,
+ const struct fib_path_ext_t_ *ext_list,
+ void *ctx);
+
+extern void fib_path_list_walk_w_ext(fib_node_index_t pl_index,
+ const fib_path_ext_list_t *ext_list,
+ fib_path_list_walk_w_ext_fn_t func,
+ void *ctx);
+
extern void fib_path_list_module_init(void);
extern void fib_path_list_module_init(void);
diff --git a/src/vnet/fib/fib_types.api b/src/vnet/fib/fib_types.api
index d946ed7..8268870 100644
--- a/src/vnet/fib/fib_types.api
+++ b/src/vnet/fib/fib_types.api
@@ -59,6 +59,7 @@
u8 is_resolve_attached;
u8 is_dvr;
u8 is_source_lookup;
+ u8 is_interface_rx;
u8 afi;
u8 next_hop[16];
u32 next_hop_id;
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 5a2aa60..d59aa23 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -810,6 +810,8 @@
path.frp_local_label = next_hop_via_label;
path.frp_eos = MPLS_NON_EOS;
}
+ if (is_local)
+ path_flags |= FIB_ROUTE_PATH_LOCAL;
if (is_dvr)
path_flags |= FIB_ROUTE_PATH_DVR;
if (is_resolve_host)
diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c
index 51d775d..ac37665 100644
--- a/src/vnet/mfib/mfib_entry.c
+++ b/src/vnet/mfib/mfib_entry.c
@@ -1324,9 +1324,10 @@
if (FIB_NODE_INDEX_INVALID != bsrc->mfes_pl)
{
- fib_path_list_walk(bsrc->mfes_pl,
- fib_path_encode,
- api_rpaths);
+ fib_path_list_walk_w_ext(bsrc->mfes_pl,
+ NULL,
+ fib_path_encode,
+ api_rpaths);
}
}
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c
index 8ae4a78..68154b3 100644
--- a/src/vnet/mfib/mfib_table.c
+++ b/src/vnet/mfib/mfib_table.c
@@ -490,6 +490,17 @@
}
u32
+mfib_table_get_table_id (u32 fib_index,
+ fib_protocol_t proto)
+{
+ mfib_table_t *mfib_table;
+
+ mfib_table = mfib_table_get(fib_index, proto);
+
+ return ((NULL != mfib_table ? mfib_table->mft_table_id : ~0));
+}
+
+u32
mfib_table_find (fib_protocol_t proto,
u32 table_id)
{
diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h
index 89f194f..6be4f79 100644
--- a/src/vnet/mfib/mfib_table.h
+++ b/src/vnet/mfib/mfib_table.h
@@ -291,6 +291,21 @@
/**
* @brief
+ * Get the Table-ID of the FIB from protocol and index
+ *
+ * @param fib_index
+ * The FIB index
+ *
+ * @paran proto
+ * The protocol of the FIB (and thus the entries therein)
+ *
+ * @return fib_index
+ * The tableID of the FIB
+ */
+extern u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
+
+/**
+ * @brief
* Get the index of the FIB for a Table-ID. This DOES NOT create the
* FIB if it does not exist.
*
diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c
index 0f2ebb1..4ac5ea7 100644
--- a/src/vnet/mpls/mpls_api.c
+++ b/src/vnet/mpls/mpls_api.c
@@ -459,7 +459,8 @@
mp->mt_sw_if_index = ntohl (mt->mt_sw_if_index);
mp->mt_count = ntohl (n);
- fib_path_list_walk (mt->mt_path_list, fib_path_encode, &api_rpaths);
+ fib_path_list_walk_w_ext (mt->mt_path_list,
+ &mt->mt_path_exts, fib_path_encode, &api_rpaths);
fp = mp->mt_paths;
vec_foreach (api_rpath, api_rpaths)