FIB: encode the label stack in the FIB path during table dump

Change-Id: I28e8a99b980ad343a4209e673201791b91ceab4e
Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
Neale Ranns
2018-12-20 03:01:49 -08:00
committed by Damjan Marion
parent a3aaa61e2f
commit 775f73c6ba
17 changed files with 236 additions and 32 deletions

View File

@ -185,7 +185,7 @@ abf_policy_send_details (u32 api, void *args)
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)

View File

@ -264,7 +264,10 @@ send_bier_route_details (const bier_table_t *bt,
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 @@ send_bier_disp_entry_details (const bier_disp_table_t *bdt,
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)

View File

@ -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 @@ void
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 @@ fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
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 @@ fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
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

View File

@ -1652,12 +1652,25 @@ void
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);
}
}

View File

@ -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 @@ format_fib_path (u8 * s, va_list * args)
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_is_looped (fib_node_index_t path_index)
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 @@ fib_path_encode (fib_node_index_t path_list_index,
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 @@ fib_path_encode (fib_node_index_t path_list_index,
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 @@ fib_path_encode (fib_node_index_t path_list_index,
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);
}

View File

@ -183,6 +183,7 @@ extern u32 fib_path_get_rpf_id(fib_node_index_t path_index);
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

View File

@ -328,11 +328,14 @@ fib_path_ext_list_find_by_path_index (const fib_path_ext_list_t *list,
{
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);

View File

@ -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 @@ fib_path_list_create (fib_path_list_flags_t flags,
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 @@ fib_path_list_create (fib_path_list_flags_t flags,
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 @@ fib_path_list_walk (fib_node_index_t path_list_index,
}
}
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)

View File

@ -183,6 +183,17 @@ extern void fib_path_list_walk(fib_node_index_t pl_index,
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);

View File

@ -59,6 +59,7 @@ typeonly define fib_path
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;

View File

@ -810,6 +810,8 @@ add_del_route_t_handler (u8 is_multipath,
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)

View File

@ -1324,9 +1324,10 @@ mfib_entry_encode (fib_node_index_t mfib_entry_index,
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);
}
}

View File

@ -489,6 +489,17 @@ mfib_table_get_index_for_sw_if_index (fib_protocol_t proto,
return (~0);
}
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)

View File

@ -289,6 +289,21 @@ extern void mfib_table_flush(u32 fib_index,
extern u32 mfib_table_get_index_for_sw_if_index(fib_protocol_t proto,
u32 sw_if_index);
/**
* @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

View File

@ -459,7 +459,8 @@ send_mpls_tunnel_entry (u32 mti, void *arg)
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)

View File

@ -8,7 +8,7 @@ from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
VppMplsLabel, MplsLspMode
VppMplsLabel, MplsLspMode, find_mpls_route
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
from scapy.packet import Raw
@ -379,6 +379,12 @@ class TestMPLS(VppTestCase):
labels=[VppMplsLabel(33)])])
route_32_eos.add_vpp_config()
self.assertTrue(
find_mpls_route(self, 0, 32, 1,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
labels=[VppMplsLabel(33)])]))
#
# a stream that matches the route for 10.0.0.1
# PG0 is in the default table

View File

@ -78,6 +78,24 @@ def find_mroute(test, grp_addr, src_addr, grp_addr_len,
return False
def find_mpls_route(test, table_id, label, eos_bit, paths=None):
dump = test.vapi.mpls_fib_dump()
for e in dump:
if label == e.label \
and eos_bit == e.eos_bit \
and table_id == e.table_id:
if not paths:
return True
else:
if (len(paths) != len(e.path)):
return False
for i in range(len(paths)):
if (paths[i] != e.path[i]):
return False
return True
return False
def fib_interface_ip_prefix(test, address, length, sw_if_index):
vp = VppIpPrefix(address, length)
addrs = test.vapi.ip_address_dump(sw_if_index, is_ipv6=vp.is_ip6)
@ -225,6 +243,23 @@ class VppMplsLabel(object):
'exp': self.exp,
'is_uniform': is_uniform}
def __eq__(self, other):
if isinstance(other, self.__class__):
return (self.value == other.value and
self.ttl == other.ttl and
self.exp == other.exp and
self.mode == other.mode)
elif hasattr(other, 'label'):
return (self.value == other.label and
self.ttl == other.ttl and
self.exp == other.exp and
(self.mode == MplsLspMode.UNIFORM) == other.is_uniform)
else:
return False
def __ne__(self, other):
return not (self == other)
class VppRoutePath(object):
@ -293,7 +328,21 @@ class VppRoutePath(object):
'label_stack': self.encode_labels()}
def __eq__(self, other):
return self.nh_addr == other.nh_addr
if isinstance(other, self.__class__):
return self.nh_addr == other.nh_addr
elif hasattr(other, 'sw_if_index'):
# vl_api_fib_path_t
if (len(self.nh_labels) != other.n_labels):
return False
for i in range(len(self.nh_labels)):
if (self.nh_labels[i] != other.label_stack[i]):
return False
return self.nh_itf == other.sw_if_index
else:
return False
def __ne__(self, other):
return not (self == other)
class VppMRoutePath(VppRoutePath):
@ -725,13 +774,8 @@ class VppMplsRoute(VppObject):
is_add=0)
def query_vpp_config(self):
dump = self._test.vapi.mpls_fib_dump()
for e in dump:
if self.local_label == e.label \
and self.eos_bit == e.eos_bit \
and self.table_id == e.table_id:
return True
return False
return find_mpls_route(self._test, self.table_id,
self.local_label, self.eos_bit)
def __str__(self):
return self.object_id()