FIB Interpose Source

The interpose source allows the source/provider to insert/interpose
a DPO in the forwarding chain of the FIB entry ahead of the forwarding
provided by the next best source. For example if the API source (i.e
the 'control plane') has provided an adjacency for forwarding, then
an interpose source (e.g. a monitoring service) couold interpose a
replicatte DPO to copy the traffic to another location AND forward
using the API's adjacency.
To use the interose feature an existing source (i.e FIB_SOURCE_PLUGIN_HI)
cn specifiy as a flag FIB_ENTRY_FLAG_INTERPOSE and provide a DPO to
interpose. One might also consider using interpose in conjunction with
FIB_ENTRY_FLAG_COVER_INHERIT to ensure the interpose object affects
all prefixes in the sub-tree.

Change-Id: I8b2737b985f8f7c08123406d0491881def347b52
Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
Neale Ranns
2018-02-21 04:57:17 -08:00
parent f55957e71c
commit 2303cb181b
35 changed files with 5481 additions and 4350 deletions
+1
View File
@@ -1082,6 +1082,7 @@ libvnet_la_SOURCES += \
vnet/fib/fib_entry_src.c \
vnet/fib/fib_entry_src_rr.c \
vnet/fib/fib_entry_src_interface.c \
vnet/fib/fib_entry_src_interpose.c \
vnet/fib/fib_entry_src_default_route.c \
vnet/fib/fib_entry_src_special.c \
vnet/fib/fib_entry_src_api.c \
+8 -4
View File
@@ -132,13 +132,17 @@ format_ip_adjacency (u8 * s, va_list * args)
vlib_counter_t counts;
vlib_get_combined_counter(&adjacency_counters, adj_index, &counts);
s = format (s, "\n counts:[%Ld:%Ld]", counts.packets, counts.bytes);
s = format (s, "\n locks:%d", adj->ia_node.fn_locks);
s = format (s, "\n counts:[%Ld:%Ld]", counts.packets, counts.bytes);
s = format (s, "\n locks:%d", adj->ia_node.fn_locks);
s = format(s, "\n delegates:\n ");
adj_delegate_format(s, adj);
s = format(s, "\n children:\n ");
s = fib_node_children_format(adj->ia_node.fn_children, s);
s = format(s, "\n children:");
if (fib_node_list_get_size(adj->ia_node.fn_children))
{
s = format(s, "\n ");
s = fib_node_children_format(adj->ia_node.fn_children, s);
}
}
return s;
-6
View File
@@ -262,16 +262,10 @@ format_adj_glean (u8* s, va_list *ap)
{
index_t index = va_arg(*ap, index_t);
CLIB_UNUSED(u32 indent) = va_arg(*ap, u32);
vnet_main_t * vnm = vnet_get_main();
ip_adjacency_t * adj = adj_get(index);
s = format(s, "%U-glean: %U",
format_fib_protocol, adj->ia_nh_proto,
format_vnet_sw_interface_name,
vnm,
vnet_get_sw_interface(vnm,
adj->rewrite_header.sw_if_index));
s = format (s, " %U",
format_vnet_rewrite,
&adj->rewrite_header, sizeof (adj->rewrite_data), 0);
+5 -54
View File
@@ -49,6 +49,7 @@
#undef vl_printfun
#include <vlibapi/api_helper_macros.h>
#include <vnet/fib/fib_api.h>
#define foreach_bier_api_msg \
_(BIER_TABLE_ADD_DEL, bier_table_add_del) \
@@ -164,7 +165,7 @@ vl_api_bier_route_add_del_t_handler (vl_api_bier_route_add_del_t * mp)
vnet_main_t *vnm;
bier_bp_t bp;
int rv = 0;
u8 ii, jj;
u8 ii;
vnm = vnet_get_main ();
vnm->api_errno = 0;
@@ -195,61 +196,11 @@ vl_api_bier_route_add_del_t_handler (vl_api_bier_route_add_del_t * mp)
vec_foreach_index(ii, brpaths)
{
brpath = &brpaths[ii];
memset(brpath, 0, sizeof(*brpath));
brpath->frp_sw_if_index = ~0;
rv = fib_path_api_parse(&mp->br_paths[ii], brpath);
vec_validate(brpath->frp_label_stack,
mp->br_paths[ii].n_labels - 1);
for (jj = 0; jj < mp->br_paths[ii].n_labels; jj++)
if (0 != rv)
{
brpath->frp_label_stack[jj].fml_value =
ntohl(mp->br_paths[ii].label_stack[jj].label);
brpath->frp_label_stack[jj].fml_ttl =
mp->br_paths[ii].label_stack[jj].ttl;
brpath->frp_label_stack[jj].fml_exp =
mp->br_paths[ii].label_stack[jj].exp;
brpath->frp_label_stack[jj].fml_mode =
(mp->br_paths[ii].label_stack[jj].is_uniform ?
FIB_MPLS_LSP_MODE_UNIFORM :
FIB_MPLS_LSP_MODE_PIPE);
}
if (mp->br_paths[ii].is_udp_encap)
{
brpath->frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
brpath->frp_udp_encap_id = ntohl(mp->br_paths[ii].next_hop_id);
}
else
{
if (0 == mp->br_paths[ii].afi)
{
clib_memcpy (&brpath->frp_addr.ip4,
mp->br_paths[ii].next_hop,
sizeof (brpath->frp_addr.ip4));
}
else
{
clib_memcpy (&brpath->frp_addr.ip6,
mp->br_paths[ii].next_hop,
sizeof (brpath->frp_addr.ip6));
}
if (ip46_address_is_zero(&brpath->frp_addr))
{
index_t bdti;
bdti = bier_disp_table_find(ntohl(mp->br_paths[ii].table_id));
if (INDEX_INVALID != bdti)
{
brpath->frp_fib_index = bdti;
brpath->frp_proto = DPO_PROTO_BIER;
}
else
{
rv = VNET_API_ERROR_NO_SUCH_FIB;
goto done;
}
}
goto done;
}
}
+2 -2
View File
@@ -356,13 +356,13 @@ format_bier_fmask (u8 *s, va_list *ap)
{
s = format(s, " output-label:%U",
format_mpls_unicast_label,
vnet_mpls_uc_get_label(bfm->bfm_label));
vnet_mpls_uc_get_label(clib_net_to_host_u32(bfm->bfm_label)));
}
else
{
s = format(s, " output-bfit:[%U]",
format_bier_bift_id,
vnet_mpls_uc_get_label(bfm->bfm_label));
vnet_mpls_uc_get_label(clib_net_to_host_u32(bfm->bfm_label)));
}
s = format(s, "\n %U%U",
format_white_space, indent,
+66 -59
View File
@@ -43,16 +43,17 @@ static int bier_test_do_debug;
if (!(_evald)) { \
fformat(stderr, "FAIL:%d: " _comment "\n", \
__LINE__, ##_args); \
res = 1; \
} else { \
if (bier_test_do_debug) \
fformat(stderr, "PASS:%d: " _comment "\n", \
__LINE__, ##_args); \
} \
_evald; \
res; \
})
#define BIER_TEST(_cond, _comment, _args...) \
{ \
if (!BIER_TEST_I(_cond, _comment, ##_args)) { \
if (BIER_TEST_I(_cond, _comment, ##_args)) { \
return 1; \
ASSERT(!("FAIL: " _comment)); \
} \
@@ -103,8 +104,10 @@ bier_test_mk_intf (u32 ninterfaces)
clib_error_t * error = NULL;
test_main_t *tm = &test_main;
u8 byte;
int res;
u32 i;
res = 0;
ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
for (i=0; i<6; i++)
@@ -146,13 +149,13 @@ bier_test_mk_intf (u32 ninterfaces)
tm->hw_if_indicies[i]);
}
return (0);
return (res);
}
#define BIER_TEST_LB(_cond, _comment, _args...) \
{ \
if (!BIER_TEST_I(_cond, _comment, ##_args)) { \
return (0); \
if (BIER_TEST_I(_cond, _comment, ##_args)) { \
return (1); \
} \
}
@@ -168,13 +171,14 @@ bier_test_validate_entry (index_t bei,
va_start(ap, n_buckets);
res = 0;
bier_entry_contribute_forwarding(bei, &dpo);
res = BIER_TEST_I((DPO_LOAD_BALANCE == dpo.dpoi_type),
"Entry links to %U",
format_dpo_type, dpo.dpoi_type);
BIER_TEST_I((DPO_LOAD_BALANCE == dpo.dpoi_type),
"Entry links to %U",
format_dpo_type, dpo.dpoi_type);
if (res)
if (!res)
{
lb = load_balance_get(dpo.dpoi_index);
res = fib_test_validate_lb_v(lb, n_buckets, &ap);
@@ -193,7 +197,9 @@ bier_test_mpls_spf (void)
u32 mpls_fib_index;
test_main_t *tm;
int lb_count;
int res;
res = 0;
lb_count = pool_elts(load_balance_pool);
tm = &test_main;
#define N_BIER_ECMP_TABLES 16
@@ -245,24 +251,24 @@ bier_test_mpls_spf (void)
BIER_TEST(FIB_NODE_INDEX_INVALID == lfei, "1600/0 is not present");
lfei = fib_table_lookup(mpls_fib_index, &pfx_1600_eos);
BIER_TEST(fib_test_validate_entry(lfei, FIB_FORW_CHAIN_TYPE_MPLS_EOS,
16,
&l_o_bt[0],
&l_o_bt[1],
&l_o_bt[2],
&l_o_bt[3],
&l_o_bt[4],
&l_o_bt[5],
&l_o_bt[6],
&l_o_bt[7],
&l_o_bt[8],
&l_o_bt[9],
&l_o_bt[10],
&l_o_bt[11],
&l_o_bt[12],
&l_o_bt[13],
&l_o_bt[14],
&l_o_bt[15]),
BIER_TEST(!fib_test_validate_entry(lfei, FIB_FORW_CHAIN_TYPE_MPLS_EOS,
16,
&l_o_bt[0],
&l_o_bt[1],
&l_o_bt[2],
&l_o_bt[3],
&l_o_bt[4],
&l_o_bt[5],
&l_o_bt[6],
&l_o_bt[7],
&l_o_bt[8],
&l_o_bt[9],
&l_o_bt[10],
&l_o_bt[11],
&l_o_bt[12],
&l_o_bt[13],
&l_o_bt[14],
&l_o_bt[15]),
"1600/1 LB stacks on BIER table %d", bti);
/*
@@ -282,24 +288,24 @@ bier_test_mpls_spf (void)
BIER_TEST(FIB_NODE_INDEX_INVALID == lfei, "1600/1 is deleted");
lfei = fib_table_lookup(mpls_fib_index, &pfx_1601_eos);
BIER_TEST(fib_test_validate_entry(lfei, FIB_FORW_CHAIN_TYPE_MPLS_EOS,
16,
&l_o_bt[0],
&l_o_bt[1],
&l_o_bt[2],
&l_o_bt[3],
&l_o_bt[4],
&l_o_bt[5],
&l_o_bt[6],
&l_o_bt[7],
&l_o_bt[8],
&l_o_bt[9],
&l_o_bt[10],
&l_o_bt[11],
&l_o_bt[12],
&l_o_bt[13],
&l_o_bt[14],
&l_o_bt[15]),
BIER_TEST(!fib_test_validate_entry(lfei, FIB_FORW_CHAIN_TYPE_MPLS_EOS,
16,
&l_o_bt[0],
&l_o_bt[1],
&l_o_bt[2],
&l_o_bt[3],
&l_o_bt[4],
&l_o_bt[5],
&l_o_bt[6],
&l_o_bt[7],
&l_o_bt[8],
&l_o_bt[9],
&l_o_bt[10],
&l_o_bt[11],
&l_o_bt[12],
&l_o_bt[13],
&l_o_bt[14],
&l_o_bt[15]),
"1601/1 LB stacks on BIER table %d", bti);
/*
@@ -411,8 +417,8 @@ bier_test_mpls_spf (void)
fib_entry_contribute_forwarding(fei,
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
&neos_dpo_1_1_1_1);
BIER_TEST(fib_test_validate_lb(&neos_dpo_1_1_1_1, 1,
&bucket_neos_99_via_10_10_10_1),
BIER_TEST(!fib_test_validate_lb(&neos_dpo_1_1_1_1, 1,
&bucket_neos_99_via_10_10_10_1),
"1.1.1.1/32 n-eos LB 1 buckets via: 99 + 10.10.10.1");
BIER_TEST(!dpo_cmp(&neos_dpo_1_1_1_1,
&bfm_1_1_1_1->bfm_dpo),
@@ -468,9 +474,9 @@ bier_test_mpls_spf (void)
fib_entry_contribute_forwarding(fei,
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
&neos_dpo_1_1_1_1);
BIER_TEST(fib_test_validate_lb(&neos_dpo_1_1_1_1, 2,
&bucket_neos_99_via_10_10_10_1,
&bucket_neos_100_via_10_10_10_2),
BIER_TEST(!fib_test_validate_lb(&neos_dpo_1_1_1_1, 2,
&bucket_neos_99_via_10_10_10_1,
&bucket_neos_100_via_10_10_10_2),
"1.1.1.1/32 n-eos LB 2 buckets "
"via: 99 + 10.10.10.1, "
"via: 100 + 10.10.10.2");
@@ -580,9 +586,9 @@ bier_test_mpls_spf (void)
input_paths_1_1_1_1 = vec_dup(paths_1_1_1_1);
bier_table_route_add(&bt_0_0_0_256, 3, input_paths_1_1_1_1);
BIER_TEST(bier_test_validate_entry(bei_3, 2,
&dpo_o_bfm_1_1_1_1,
&dpo_o_bfm_1_1_1_2),
BIER_TEST(!bier_test_validate_entry(bei_3, 2,
&dpo_o_bfm_1_1_1_1,
&dpo_o_bfm_1_1_1_2),
"BP:3 stacks on fmask 1.1.1.2 & 1.1.1.1");
/*
@@ -632,9 +638,9 @@ bier_test_mpls_spf (void)
/* suspend so the update walk kicks int */
vlib_process_suspend(vlib_get_main(), 1e-5);
BIER_TEST(bier_test_validate_entry(bei_3, 2,
&dpo_o_bfm_1_1_1_1,
&dpo_o_bfm_1_1_1_2),
BIER_TEST(!bier_test_validate_entry(bei_3, 2,
&dpo_o_bfm_1_1_1_1,
&dpo_o_bfm_1_1_1_2),
"BP:3 stacks on fmask 1.1.1.2 & 1.1.1.1");
BIER_TEST((bier_table_fwd_lookup(bier_table_get(l_o_bt[0].bier.table), 3) ==
bfmi_1_1_1_1),
@@ -716,9 +722,7 @@ static int
bier_test_mpls_imp (void)
{
fib_node_index_t bii;
/* test_main_t *tm; */
/* tm = &test_main; */
int res;
/*
* Add the BIER Main table
@@ -740,6 +744,7 @@ bier_test_mpls_imp (void)
u8 buckets[BIER_HDR_BUCKETS_256];
memset(buckets, 0x5, BIER_HDR_BUCKETS_256);
res = 0;
bier_bit_string_init(&bbs_256, BIER_HDR_LEN_256, buckets);
bii = bier_imp_add_or_lock(&bt_0_0_0_256, 1, &bbs_256);
@@ -797,7 +802,9 @@ bier_test_mpls_disp (void)
.bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
};
index_t bti;
int res;
res = 0;
bti = bier_table_add_or_lock(&bt_0_0_0_256, 1600);
/*
+41 -12
View File
@@ -153,20 +153,22 @@ format_dpo_id (u8 * s, va_list * args)
if (NULL != dpo_vfts[dpo->dpoi_type].dv_format)
{
return (format(s, "%U",
dpo_vfts[dpo->dpoi_type].dv_format,
dpo->dpoi_index,
indent));
s = format(s, "%U",
dpo_vfts[dpo->dpoi_type].dv_format,
dpo->dpoi_index,
indent);
}
switch (dpo->dpoi_type)
else
{
case DPO_FIRST:
s = format(s, "unset");
break;
default:
s = format(s, "unknown");
break;
switch (dpo->dpoi_type)
{
case DPO_FIRST:
s = format(s, "unset");
break;
default:
s = format(s, "unknown");
break;
}
}
return (s);
}
@@ -303,6 +305,18 @@ dpo_default_get_next_node (const dpo_id_t *dpo)
return (node_indices);
}
/**
* A default variant of the make interpose function that just returns
* the original
*/
static void
dpo_default_mk_interpose (const dpo_id_t *original,
const dpo_id_t *parent,
dpo_id_t *clone)
{
dpo_copy(clone, original);
}
void
dpo_register (dpo_type_t type,
const dpo_vft_t *vft,
@@ -314,6 +328,10 @@ dpo_register (dpo_type_t type,
{
dpo_vfts[type].dv_get_next_node = dpo_default_get_next_node;
}
if (NULL == dpo_vfts[type].dv_mk_interpose)
{
dpo_vfts[type].dv_mk_interpose = dpo_default_mk_interpose;
}
vec_validate(dpo_nodes, type);
dpo_nodes[type] = nodes;
@@ -330,6 +348,17 @@ dpo_register_new_type (const dpo_vft_t *vft,
return (type);
}
void
dpo_mk_interpose (const dpo_id_t *original,
const dpo_id_t *parent,
dpo_id_t *clone)
{
if (!dpo_id_is_valid(original))
return;
dpo_vfts[original->dpoi_type].dv_mk_interpose(original, parent, clone);
}
void
dpo_lock (dpo_id_t *dpo)
{
+24
View File
@@ -224,6 +224,14 @@ extern void dpo_lock(dpo_id_t *dpo);
*/
extern void dpo_unlock(dpo_id_t *dpo);
/**
* @brief
* Make an interpose DPO from an original
*/
extern void dpo_mk_interpose(const dpo_id_t *original,
const dpo_id_t *parent,
dpo_id_t *clone);
/**
* @brief Set/create a DPO ID
* The DPO will be locked.
@@ -373,6 +381,18 @@ typedef u32* (*dpo_get_next_node_t)(const dpo_id_t *dpo);
*/
typedef u32 (*dpo_get_urpf_t)(const dpo_id_t *dpo);
/**
* @brief Called during FIB interposition when the originally
* registered DPO is used to 'clone' an instance for interposition
* at a particular location in the FIB graph.
* The parent is the next DPO in the chain that the clone will
* be used instead of. The clone may then choose to stack itself
* on the parent.
*/
typedef void (*dpo_mk_interpose_t)(const dpo_id_t *original,
const dpo_id_t *parent,
dpo_id_t *clone);
/**
* @brief A virtual function table regisitered for a DPO type
*/
@@ -405,6 +425,10 @@ typedef struct dpo_vft_t_
* Get uRPF interface
*/
dpo_get_urpf_t dv_get_urpf;
/**
* Signal on an interposed child that the parent has changed
*/
dpo_mk_interpose_t dv_mk_interpose;
} dpo_vft_t;
+10 -10
View File
@@ -198,16 +198,6 @@ load_balance_create (u32 n_buckets,
return (load_balance_get_index(load_balance_create_i(n_buckets, lb_proto, fhc)));
}
u16
load_balance_n_buckets (index_t lbi)
{
load_balance_t *lb;
lb = load_balance_get(lbi);
return (lb->lb_n_buckets);
}
static inline void
load_balance_set_bucket_i (load_balance_t *lb,
u32 bucket,
@@ -250,6 +240,16 @@ load_balance_is_drop (const dpo_id_t *dpo)
return (0);
}
u16
load_balance_n_buckets (index_t lbi)
{
load_balance_t *lb;
lb = load_balance_get(lbi);
return (lb->lb_n_buckets);
}
void
load_balance_set_fib_entry_flags (index_t lbi,
fib_entry_flag_t flags)
+33
View File
@@ -1204,11 +1204,44 @@ mpls_label_dpo_mem_show (void)
sizeof(mpls_label_dpo_t));
}
/**
* Interpose a label DPO. used in the FIB unit tests
*/
static void
mpls_label_interpose (const dpo_id_t *original,
const dpo_id_t *parent,
dpo_id_t *clone)
{
mpls_label_dpo_t *mld, *mld_clone;
mld_clone = mpls_label_dpo_alloc();
mld = mpls_label_dpo_get(original->dpoi_index);
mld_clone->mld_locks = 0;
clib_memcpy(&mld_clone->mld_hdr,
&mld->mld_hdr,
sizeof(mld_clone->mld_hdr));
mld_clone->mld_payload_proto = mld->mld_payload_proto;
mld_clone->mld_n_labels = mld->mld_n_labels;
mld_clone->mld_n_hdr_bytes = mld->mld_n_hdr_bytes;
dpo_stack(mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE],
mld_clone->mld_payload_proto,
&mld_clone->mld_dpo,
parent);
dpo_set(clone,
mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE],
mld_clone->mld_payload_proto,
mpls_label_dpo_get_index(mld_clone));
}
const static dpo_vft_t mld_vft = {
.dv_lock = mpls_label_dpo_lock,
.dv_unlock = mpls_label_dpo_unlock,
.dv_format = format_mpls_label_dpo,
.dv_mem_show = mpls_label_dpo_mem_show,
.dv_mk_interpose = mpls_label_interpose,
};
const static char* const mpls_label_imp_pipe_ip4_nodes[] =
+6 -4
View File
@@ -53,7 +53,7 @@ extern replicate_main_t replicate_main;
*/
typedef struct replicate_t_ {
/**
* number of buckets in the load-balance. always a power of 2.
* number of buckets in the replicate.
*/
u16 rep_n_buckets;
@@ -104,15 +104,17 @@ extern void replicate_multipath_update(
load_balance_path_t *next_hops);
extern void replicate_set_bucket(index_t repi,
u32 bucket,
const dpo_id_t *next);
u32 bucket,
const dpo_id_t *next);
extern u8* format_replicate(u8 * s, va_list * args);
extern const dpo_id_t *replicate_get_bucket(index_t repi,
u32 bucket);
u32 bucket);
extern int replicate_is_drop(const dpo_id_t *dpo);
extern u16 replicate_n_buckets(index_t repi);
/**
* The encapsulation breakages are for fast DP access
*/
+1 -1
View File
@@ -979,7 +979,7 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
/*
* we're looking for FIB entries that indicate the source
* is attached. There may be more specific non-attached
* routes tht match the source, but these do not influence
* routes that match the source, but these do not influence
* whether we respond to an ARP request, i.e. they do not
* influence whether we are the correct way for the sender
* to reach us, they only affect how we reach the sender.
+1
View File
@@ -266,3 +266,4 @@ fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
out->next_hop_id = api_rpath->rpath.frp_udp_encap_id;
}
}
+12
View File
@@ -61,4 +61,16 @@ struct _vl_api_fib_path;
extern void fib_api_path_encode (const fib_route_path_encode_t * api_rpath,
struct _vl_api_fib_path *out);
void
fib_prefix_to_api (const fib_prefix_t *pfx,
u8 address[16],
u8 *length,
u8 *is_ip6);
struct _vl_api_fib_path;
extern int fib_path_api_parse(const struct _vl_api_fib_path *in,
fib_route_path_t *out);
#endif /* __FIB_API_H__ */
+2 -1
View File
@@ -20,6 +20,7 @@
#include <vnet/fib/fib_entry_cover.h>
#include <vnet/fib/fib_entry_src.h>
#include <vnet/fib/fib_entry_delegate.h>
#include <vnet/dpo/drop_dpo.h>
/**
* A description of the need to import routes from the export table
@@ -184,7 +185,7 @@ fib_entry_import_add (fib_ae_import_t *import,
dpo = fib_entry_contribute_ip_forwarding(entry_index);
if (dpo_id_is_valid(dpo))
if (dpo_id_is_valid(dpo) && !dpo_is_drop(dpo))
{
fib_table_entry_special_dpo_add(import->faei_import_fib,
&prefix,
+85 -102
View File
File diff suppressed because it is too large Load Diff
+50 -10
View File
@@ -127,10 +127,17 @@ typedef enum fib_source_t_ {
* 'ip route' sources when provided
*/
FIB_SOURCE_DEFAULT_ROUTE,
/**
* The interpose source.
* This is not a real source, so don't use it to source a prefix.
* It exists here to provide a value against which to register to the
* VFT for providing the interpose actions to a real source.
*/
FIB_SOURCE_INTERPOSE,
/**
* Marker. add new entries before this one.
*/
FIB_SOURCE_LAST = FIB_SOURCE_DEFAULT_ROUTE,
FIB_SOURCE_LAST = FIB_SOURCE_INTERPOSE,
} __attribute__ ((packed)) fib_source_t;
STATIC_ASSERT (sizeof(fib_source_t) == 1,
@@ -162,6 +169,7 @@ STATIC_ASSERT (sizeof(fib_source_t) == 1,
[FIB_SOURCE_URPF_EXEMPT] = "urpf-exempt", \
[FIB_SOURCE_DEFAULT_ROUTE] = "default-route", \
[FIB_SOURCE_PLUGIN_HI] = "plugin-hi", \
[FIB_SOURCE_INTERPOSE] = "interpose", \
}
#define FOR_EACH_FIB_SOURCE(_item) \
@@ -222,10 +230,16 @@ typedef enum fib_entry_attribute_t_ {
* that is covers
*/
FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT,
/**
* The interpose attribute.
* place the forwarding provided by the source infront of the forwarding
* provided by the best source, or failing that, by the cover.
*/
FIB_ENTRY_ATTRIBUTE_INTERPOSE,
/**
* Marker. add new entries before this one.
*/
FIB_ENTRY_ATTRIBUTE_LAST = FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT,
FIB_ENTRY_ATTRIBUTE_LAST = FIB_ENTRY_ATTRIBUTE_INTERPOSE,
} fib_entry_attribute_t;
#define FIB_ENTRY_ATTRIBUTES { \
@@ -239,6 +253,7 @@ typedef enum fib_entry_attribute_t_ {
[FIB_ENTRY_ATTRIBUTE_MULTICAST] = "multicast", \
[FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT] = "no-attached-export", \
[FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT] = "covered-inherit", \
[FIB_ENTRY_ATTRIBUTE_INTERPOSE] = "interpose", \
}
#define FOR_EACH_FIB_ATTRIBUTE(_item) \
@@ -258,6 +273,7 @@ typedef enum fib_entry_flag_t_ {
FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT = (1 << FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT),
FIB_ENTRY_FLAG_MULTICAST = (1 << FIB_ENTRY_ATTRIBUTE_MULTICAST),
FIB_ENTRY_FLAG_COVERED_INHERIT = (1 << FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT),
FIB_ENTRY_FLAG_INTERPOSE = (1 << FIB_ENTRY_ATTRIBUTE_INTERPOSE),
} __attribute__((packed)) fib_entry_flag_t;
/**
@@ -272,6 +288,10 @@ typedef enum fib_entry_src_attribute_t_ {
* the source has been added to the entry
*/
FIB_ENTRY_SRC_ATTRIBUTE_ADDED = FIB_ENTRY_SRC_ATTRIBUTE_FIRST,
/**
* the source is contributing forwarding
*/
FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING,
/**
* the source is active/best
*/
@@ -286,22 +306,23 @@ typedef enum fib_entry_src_attribute_t_ {
FIB_ENTRY_SRC_ATTRIBUTE_LAST = FIB_ENTRY_SRC_ATTRIBUTE_INHERITED,
} fib_entry_src_attribute_t;
#define FIB_ENTRY_SRC_ATTRIBUTE_MAX (FIB_ENTRY_SRC_ATTRIBUTE_LAST+1)
#define FIB_ENTRY_SRC_ATTRIBUTES { \
[FIB_ENTRY_SRC_ATTRIBUTE_ADDED] = "added", \
[FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING] = "contributing", \
[FIB_ENTRY_SRC_ATTRIBUTE_ACTIVE] = "active", \
[FIB_ENTRY_SRC_ATTRIBUTE_INHERITED] = "inherited", \
}
#define FOR_EACH_FIB_SRC_ATTRIBUTE(_item) \
for (_item = FIB_ENTRY_SRC_ATTRIBUTE_FIRST; \
_item < FIB_ENTRY_SRC_ATTRIBUTE_MAX; \
_item <= FIB_ENTRY_SRC_ATTRIBUTE_LAST; \
_item++)
typedef enum fib_entry_src_flag_t_ {
FIB_ENTRY_SRC_FLAG_NONE = 0,
FIB_ENTRY_SRC_FLAG_ADDED = (1 << FIB_ENTRY_SRC_ATTRIBUTE_ADDED),
FIB_ENTRY_SRC_FLAG_CONTRIBUTING = (1 << FIB_ENTRY_SRC_ATTRIBUTE_CONTRIBUTING),
FIB_ENTRY_SRC_FLAG_ACTIVE = (1 << FIB_ENTRY_SRC_ATTRIBUTE_ACTIVE),
FIB_ENTRY_SRC_FLAG_INHERITED = (1 << FIB_ENTRY_SRC_ATTRIBUTE_INHERITED),
} __attribute__ ((packed)) fib_entry_src_flag_t;
@@ -326,10 +347,17 @@ typedef struct fib_entry_src_t_ {
* The path-list created by the source
*/
fib_node_index_t fes_pl;
/**
* Flags the source contributes to the entry
*/
fib_entry_flag_t fes_entry_flags;
/**
* Which source this info block is for
*/
fib_source_t fes_src;
/**
* Flags on the source
*/
@@ -341,11 +369,6 @@ typedef struct fib_entry_src_t_ {
* of times a given source has been added. Which is even fewer
*/
u8 fes_ref_count;
/**
* Flags the source contributes to the entry
*/
fib_entry_flag_t fes_entry_flags;
/**
* Source specific info
@@ -361,6 +384,21 @@ typedef struct fib_entry_src_t_ {
*/
u32 fesr_sibling;
} rr;
struct {
/**
* the index of the FIB entry that is the covering entry
*/
fib_node_index_t fesi_cover;
/**
* This source's index in the cover's list
*/
u32 fesi_sibling;
/**
* DPO type to interpose. The dpo type needs to have registered
* it's 'contribute interpose' callback function.
*/
dpo_id_t fesi_dpo;
} interpose;
struct {
/**
* the index of the FIB entry that is the covering entry
@@ -398,7 +436,7 @@ typedef struct fib_entry_src_t_ {
*/
fib_node_index_t fesl_fib_index;
} lisp;
};
} u;
} fib_entry_src_t;
/**
@@ -509,6 +547,8 @@ extern void fib_entry_inherit(fib_node_index_t cover,
extern fib_entry_src_flag_t fib_entry_delete(fib_node_index_t fib_entry_index,
fib_source_t source);
extern void fib_entry_recalculate_forwarding(
fib_node_index_t fib_entry_index);
extern void fib_entry_contribute_urpf(fib_node_index_t path_index,
index_t urpf);
extern void fib_entry_contribute_forwarding(
File diff suppressed because it is too large Load Diff
+55 -13
View File
@@ -172,6 +172,26 @@ typedef void (*fib_entry_src_set_data_t)(fib_entry_src_t *src,
typedef const void* (*fib_entry_src_get_data_t)(fib_entry_src_t *src,
const fib_entry_t *fib_entry);
/**
* Contribute forwarding to interpose inthe chain
*/
typedef const dpo_id_t* (*fib_entry_src_contribute_interpose_t)(const fib_entry_src_t *src,
const fib_entry_t *fib_entry);
/**
* The fib entry flags for this source are changing
*/
typedef void (*fib_entry_src_flag_change_t)(fib_entry_src_t *src,
const fib_entry_t *fib_entry,
fib_entry_flag_t new_flags);
/**
* The fib entry flags for this source are changing
*/
typedef void (*fib_entry_src_copy_t)(const fib_entry_src_t *orig_src,
const fib_entry_t *fib_entry,
fib_entry_src_t *copy_src);
/**
* Virtual function table each FIB entry source will register
*/
@@ -193,21 +213,48 @@ typedef struct fib_entry_src_vft_t_ {
fib_entry_src_fwd_update_t fesv_fwd_update;
fib_entry_src_get_data_t fesv_get_data;
fib_entry_src_set_data_t fesv_set_data;
fib_entry_src_contribute_interpose_t fesv_contribute_interpose;
fib_entry_src_flag_change_t fesv_flags_change;
fib_entry_src_copy_t fesv_copy;
} fib_entry_src_vft_t;
#define FOR_EACH_SRC_ADDED(_entry, _src, _source, action) \
{ \
vec_foreach(_src, _entry->fe_srcs) \
vec_foreach(_src, (_entry)->fe_srcs) \
{ \
if (_src->fes_flags & FIB_ENTRY_SRC_FLAG_ADDED) { \
_source = _src->fes_src; \
do { \
action; \
} while(0); \
_source = (_src)->fes_src; \
action; \
} \
} \
}
#define FIB_ENTRY_SRC_VFT_INVOKE(esrc, func, args) \
{ \
const fib_entry_src_vft_t *_vft; \
_vft = fib_entry_src_get_vft(esrc); \
if (_vft->func) \
_vft->func args; \
}
#define FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, func, args) \
{ \
const fib_entry_src_vft_t *_vft; \
_vft = fib_entry_src_get_vft(esrc); \
if (_vft->func) \
return (_vft->func args); \
}
#define FIB_ENTRY_SRC_VFT_EXISTS(esrc, func) \
{ \
const fib_entry_src_vft_t *_vft; \
_vft = fib_entry_src_get_vft(esrc); \
(_vft->func); \
}
extern const fib_entry_src_vft_t*fib_entry_src_get_vft(
const fib_entry_src_t *esrc);
extern u8* fib_entry_src_format(fib_entry_t *entry,
fib_source_t source,
u8* s);
@@ -215,19 +262,13 @@ extern u8* fib_entry_src_format(fib_entry_t *entry,
extern void fib_entry_src_register(fib_source_t source,
const fib_entry_src_vft_t *vft);
extern void fib_entry_src_action_init(fib_entry_t *entry,
fib_source_t source);
extern void fib_entry_src_action_deinit(fib_entry_t *fib_entry,
fib_source_t source);
extern fib_entry_src_cover_res_t fib_entry_src_action_cover_change(
fib_entry_t *entry,
fib_source_t source);
fib_entry_src_t *esrc);
extern fib_entry_src_cover_res_t fib_entry_src_action_cover_update(
fib_entry_t *fib_entry,
fib_source_t source);
fib_entry_src_t *esrc);
extern void fib_entry_src_action_activate(fib_entry_t *fib_entry,
fib_source_t source);
@@ -304,6 +345,7 @@ extern void fib_entry_source_change(fib_entry_t *fib_entry,
extern void fib_entry_src_default_register(void);
extern void fib_entry_src_rr_register(void);
extern void fib_entry_src_interface_register(void);
extern void fib_entry_src_interpose_register(void);
extern void fib_entry_src_default_route_register(void);
extern void fib_entry_src_special_register(void);
extern void fib_entry_src_api_register(void);
+19 -19
View File
@@ -27,8 +27,8 @@
static void
fib_entry_src_adj_init (fib_entry_src_t *src)
{
src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
src->adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
src->u.adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
}
static void
@@ -211,17 +211,17 @@ fib_entry_src_adj_activate (fib_entry_src_t *src,
* find the covering prefix. become a dependent thereof.
* there should always be a cover, though it may be the default route.
*/
src->adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix);
src->u.adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix);
ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
ASSERT(fib_entry_get_index(fib_entry) != src->adj.fesa_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
ASSERT(fib_entry_get_index(fib_entry) != src->u.adj.fesa_cover);
cover = fib_entry_get(src->adj.fesa_cover);
cover = fib_entry_get(src->u.adj.fesa_cover);
ASSERT(cover != fib_entry);
src->adj.fesa_sibling =
src->u.adj.fesa_sibling =
fib_entry_cover_track(cover,
fib_entry_get_index(fib_entry));
@@ -240,7 +240,7 @@ fib_entry_src_adj_activate (fib_entry_src_t *src,
if (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover))
{
fib_entry_src_path_list_walk_cxt_t ctx = {
.cover_itf = fib_entry_get_resolving_interface(src->adj.fesa_cover),
.cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
.flags = FIB_PATH_EXT_ADJ_FLAG_NONE,
.src = src,
};
@@ -267,7 +267,7 @@ fib_entry_src_adj_reactivate (fib_entry_src_t *src,
const fib_entry_t *fib_entry)
{
fib_entry_src_path_list_walk_cxt_t ctx = {
.cover_itf = fib_entry_get_resolving_interface(src->adj.fesa_cover),
.cover_itf = fib_entry_get_resolving_interface(src->u.adj.fesa_cover),
.flags = FIB_PATH_EXT_ADJ_FLAG_NONE,
.src = src,
};
@@ -292,24 +292,24 @@ fib_entry_src_adj_deactivate (fib_entry_src_t *src,
/*
* remove the depednecy on the covering entry
*/
ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
cover = fib_entry_get(src->adj.fesa_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
cover = fib_entry_get(src->u.adj.fesa_cover);
fib_entry_cover_untrack(cover, src->adj.fesa_sibling);
fib_entry_cover_untrack(cover, src->u.adj.fesa_sibling);
/*
* tell the cover this entry no longer needs exporting
*/
fib_attached_export_covered_removed(cover, fib_entry_get_index(fib_entry));
src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
src->u.adj.fesa_cover = FIB_NODE_INDEX_INVALID;
}
static u8*
fib_entry_src_adj_format (fib_entry_src_t *src,
u8* s)
{
return (format(s, " cover:%d", src->adj.fesa_cover));
return (format(s, " cover:%d", src->u.adj.fesa_cover));
}
static void
@@ -321,8 +321,8 @@ fib_entry_src_adj_installed (fib_entry_src_t *src,
*/
fib_entry_t *cover;
ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
cover = fib_entry_get(src->adj.fesa_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
cover = fib_entry_get(src->u.adj.fesa_cover);
fib_attached_export_covered_added(cover,
fib_entry_get_index(fib_entry));
@@ -369,9 +369,9 @@ fib_entry_src_adj_cover_update (fib_entry_src_t *src,
};
fib_entry_t *cover;
ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.adj.fesa_cover);
cover = fib_entry_get(src->adj.fesa_cover);
cover = fib_entry_get(src->u.adj.fesa_cover);
res.install = (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover));
+18 -17
View File
@@ -27,8 +27,8 @@
static void
fib_entry_src_interface_init (fib_entry_src_t *src)
{
src->interface.fesi_cover = FIB_NODE_INDEX_INVALID;
src->interface.fesi_sibling = FIB_NODE_INDEX_INVALID;
src->u.interface.fesi_cover = FIB_NODE_INDEX_INVALID;
src->u.interface.fesi_sibling = FIB_NODE_INDEX_INVALID;
}
static void
@@ -74,7 +74,7 @@ fib_entry_src_interface_path_swap (fib_entry_src_t *src,
{
/*
* the connected prefix will link to a glean on a non-p2p
* interface.
* u.interface.
*/
adj->sub_type.glean.receive_addr = entry->fe_prefix.fp_addr;
}
@@ -98,15 +98,15 @@ fib_entry_src_interface_activate (fib_entry_src_t *src,
* during an attached export of the cover, this local prefix is
* also exported
*/
src->interface.fesi_cover =
src->u.interface.fesi_cover =
fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix);
ASSERT(FIB_NODE_INDEX_INVALID != src->interface.fesi_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover);
cover = fib_entry_get(src->interface.fesi_cover);
cover = fib_entry_get(src->u.interface.fesi_cover);
src->interface.fesi_sibling =
src->u.interface.fesi_sibling =
fib_entry_cover_track(cover, fib_entry_get_index(fib_entry));
}
@@ -127,13 +127,13 @@ fib_entry_src_interface_deactivate (fib_entry_src_t *src,
/*
* remove the depednecy on the covering entry
*/
if (FIB_NODE_INDEX_INVALID != src->interface.fesi_cover)
if (FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover)
{
cover = fib_entry_get(src->interface.fesi_cover);
cover = fib_entry_get(src->u.interface.fesi_cover);
fib_entry_cover_untrack(cover, src->interface.fesi_sibling);
fib_entry_cover_untrack(cover, src->u.interface.fesi_sibling);
src->interface.fesi_cover = FIB_NODE_INDEX_INVALID;
src->u.interface.fesi_cover = FIB_NODE_INDEX_INVALID;
}
}
@@ -146,7 +146,7 @@ fib_entry_src_interface_cover_change (fib_entry_src_t *src,
.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
};
if (FIB_NODE_INDEX_INVALID == src->interface.fesi_cover)
if (FIB_NODE_INDEX_INVALID == src->u.interface.fesi_cover)
{
/*
* not tracking the cover. surprised we got poked?
@@ -159,8 +159,9 @@ fib_entry_src_interface_cover_change (fib_entry_src_t *src,
* entry inserted benaeth it. That does not necessarily mean that this
* entry is covered by the new prefix. check that
*/
if (src->rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix))
if (src->u.interface.fesi_cover !=
fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix))
{
fib_entry_src_interface_deactivate(src, fib_entry);
fib_entry_src_interface_activate(src, fib_entry);
@@ -177,9 +178,9 @@ fib_entry_src_interface_installed (fib_entry_src_t *src,
*/
fib_entry_t *cover;
if (FIB_NODE_INDEX_INVALID != src->interface.fesi_cover)
if (FIB_NODE_INDEX_INVALID != src->u.interface.fesi_cover)
{
cover = fib_entry_get(src->interface.fesi_cover);
cover = fib_entry_get(src->u.interface.fesi_cover);
fib_attached_export_covered_added(cover,
fib_entry_get_index(fib_entry));
@@ -190,7 +191,7 @@ static u8*
fib_entry_src_interface_format (fib_entry_src_t *src,
u8* s)
{
return (format(s, " cover:%d", src->interface.fesi_cover));
return (format(s, " cover:%d", src->u.interface.fesi_cover));
}
const static fib_entry_src_vft_t interface_src_vft = {
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -104,14 +104,14 @@ fib_entry_src_lisp_set_data (fib_entry_src_t *src,
const fib_entry_t *entry,
const void *data)
{
src->lisp.fesl_fib_index = *(u32*)data;
src->u.lisp.fesl_fib_index = *(u32*)data;
}
static const void*
fib_entry_src_lisp_get_data (fib_entry_src_t *src,
const fib_entry_t *entry)
{
return (&(src->lisp.fesl_fib_index));
return (&(src->u.lisp.fesl_fib_index));
}
const static fib_entry_src_vft_t api_src_vft = {
+58 -60
View File
@@ -22,7 +22,7 @@
#include <vnet/fib/mpls_fib.h>
/**
* Source initialisation Function
* Source initialisation Function
*/
static void
fib_entry_src_mpls_init (fib_entry_src_t *src)
@@ -30,16 +30,16 @@ fib_entry_src_mpls_init (fib_entry_src_t *src)
mpls_eos_bit_t eos;
src->fes_flags = FIB_ENTRY_SRC_FLAG_NONE;
src->mpls.fesm_label = MPLS_LABEL_INVALID;
src->u.mpls.fesm_label = MPLS_LABEL_INVALID;
FOR_EACH_MPLS_EOS_BIT(eos)
{
src->mpls.fesm_lfes[eos] = FIB_NODE_INDEX_INVALID;
src->u.mpls.fesm_lfes[eos] = FIB_NODE_INDEX_INVALID;
}
}
/**
* Source deinitialisation Function
* Source deinitialisation Function
*/
static void
fib_entry_src_mpls_deinit (fib_entry_src_t *src)
@@ -50,7 +50,7 @@ static void
fib_entry_src_mpls_remove (fib_entry_src_t *src)
{
src->fes_pl = FIB_NODE_INDEX_INVALID;
src->mpls.fesm_label = MPLS_LABEL_INVALID;
src->u.mpls.fesm_label = MPLS_LABEL_INVALID;
}
static void
@@ -61,9 +61,9 @@ fib_entry_src_mpls_add (fib_entry_src_t *src,
const dpo_id_t *dpo)
{
src->fes_pl =
fib_path_list_create_special(proto,
FIB_PATH_LIST_FLAG_DROP,
drop_dpo_get(proto));
fib_path_list_create_special(proto,
FIB_PATH_LIST_FLAG_DROP,
drop_dpo_get(proto));
}
static void
@@ -91,71 +91,71 @@ fib_entry_src_mpls_set_data (fib_entry_src_t *src,
*/
FOR_EACH_MPLS_EOS_BIT(eos)
{
fib_table_entry_delete_index(src->mpls.fesm_lfes[eos],
FIB_SOURCE_SPECIAL);
fib_table_entry_delete_index(src->u.mpls.fesm_lfes[eos],
FIB_SOURCE_SPECIAL);
}
fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID,
FIB_PROTOCOL_MPLS,
FIB_SOURCE_MPLS);
src->mpls.fesm_label = label;
src->u.mpls.fesm_label = label;
}
else
{
fib_prefix_t prefix = {
.fp_proto = FIB_PROTOCOL_MPLS,
.fp_label = label,
};
fib_node_index_t fib_index;
dpo_id_t dpo = DPO_INVALID;
fib_prefix_t prefix = {
.fp_proto = FIB_PROTOCOL_MPLS,
.fp_label = label,
};
fib_node_index_t fib_index;
dpo_id_t dpo = DPO_INVALID;
/*
* adding a new local label. make sure the MPLS fib exists.
*/
if (MPLS_LABEL_INVALID == src->mpls.fesm_label)
if (MPLS_LABEL_INVALID == src->u.mpls.fesm_label)
{
fib_index =
fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS,
MPLS_FIB_DEFAULT_TABLE_ID,
fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS,
MPLS_FIB_DEFAULT_TABLE_ID,
FIB_SOURCE_MPLS);
}
else
{
fib_index = mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID);
else
{
fib_index = mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID);
/*
* if this is a change in label, reomve the old one first
*/
if (src->mpls.fesm_label != label)
{
FOR_EACH_MPLS_EOS_BIT(eos)
{
ASSERT(FIB_NODE_INDEX_INVALID != src->mpls.fesm_lfes[eos]);
fib_table_entry_delete_index(src->mpls.fesm_lfes[eos],
FIB_SOURCE_SPECIAL);
}
}
}
/*
* if this is a change in label, reomve the old one first
*/
if (src->u.mpls.fesm_label != label)
{
FOR_EACH_MPLS_EOS_BIT(eos)
{
ASSERT(FIB_NODE_INDEX_INVALID != src->u.mpls.fesm_lfes[eos]);
fib_table_entry_delete_index(src->u.mpls.fesm_lfes[eos],
FIB_SOURCE_SPECIAL);
}
}
}
src->mpls.fesm_label = label;
src->u.mpls.fesm_label = label;
FOR_EACH_MPLS_EOS_BIT(eos)
{
prefix.fp_eos = eos;
prefix.fp_payload_proto = fib_proto_to_dpo(payload_proto);
FOR_EACH_MPLS_EOS_BIT(eos)
{
prefix.fp_eos = eos;
prefix.fp_payload_proto = fib_proto_to_dpo(payload_proto);
fib_entry_contribute_forwarding(fei,
(eos ?
FIB_FORW_CHAIN_TYPE_MPLS_EOS :
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS),
&dpo);
src->mpls.fesm_lfes[eos] =
fib_table_entry_special_dpo_add(fib_index,
&prefix,
FIB_SOURCE_SPECIAL,
FIB_ENTRY_FLAG_EXCLUSIVE,
&dpo);
dpo_reset(&dpo);
}
fib_entry_contribute_forwarding(fei,
(eos ?
FIB_FORW_CHAIN_TYPE_MPLS_EOS :
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS),
&dpo);
src->u.mpls.fesm_lfes[eos] =
fib_table_entry_special_dpo_add(fib_index,
&prefix,
FIB_SOURCE_SPECIAL,
FIB_ENTRY_FLAG_EXCLUSIVE,
&dpo);
dpo_reset(&dpo);
}
}
}
@@ -163,14 +163,14 @@ static const void *
fib_entry_src_mpls_get_data (fib_entry_src_t *src,
const fib_entry_t *entry)
{
return (&(src->mpls.fesm_label));
return (&(src->u.mpls.fesm_label));
}
static u8*
fib_entry_src_mpls_format (fib_entry_src_t *src,
u8* s)
u8* s)
{
return (format(s, " local-label:%d", src->mpls.fesm_label));
return (format(s, " local-label:%d", src->u.mpls.fesm_label));
}
const static fib_entry_src_vft_t mpls_src_vft = {
@@ -193,7 +193,5 @@ const static fib_entry_src_vft_t mpls_src_vft = {
void
fib_entry_src_mpls_register (void)
{
fib_entry_src_register(FIB_SOURCE_MPLS, &mpls_src_vft);
fib_entry_src_register(FIB_SOURCE_MPLS, &mpls_src_vft);
}
+22 -20
View File
@@ -20,6 +20,7 @@
#include <vnet/dpo/drop_dpo.h>
#include "fib_entry_src.h"
#include "fib_entry_src_rr.h"
#include "fib_entry_cover.h"
#include "fib_entry.h"
#include "fib_table.h"
@@ -29,7 +30,7 @@
*
* Resolve via a connected cover.
*/
static void
void
fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
const fib_entry_t *fib_entry,
const fib_entry_t *cover)
@@ -53,7 +54,8 @@ fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
* shortly to over-rule this RR source.
*/
src->fes_pl = fib_path_list_create(FIB_PATH_LIST_FLAG_NONE, paths);
src->fes_entry_flags = fib_entry_get_flags(fib_entry_get_index(cover));
src->fes_entry_flags |= (fib_entry_get_flags(fib_entry_get_index(cover)) &
FIB_ENTRY_FLAGS_RR_INHERITED);
vec_free(paths);
}
@@ -65,8 +67,8 @@ fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
static void
fib_entry_src_rr_init (fib_entry_src_t *src)
{
src->rr.fesr_cover = FIB_NODE_INDEX_INVALID;
src->rr.fesr_sibling = FIB_NODE_INDEX_INVALID;
src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;
src->u.rr.fesr_sibling = FIB_NODE_INDEX_INVALID;
}
@@ -84,7 +86,7 @@ fib_entry_src_rr_init (fib_entry_src_t *src)
* the loop will break when the cover changes, and this function
* will be called again when that happens.
*/
static void
void
fib_entry_src_rr_use_covers_pl (fib_entry_src_t *src,
const fib_entry_t *fib_entry,
const fib_entry_t *cover)
@@ -132,14 +134,14 @@ fib_entry_src_rr_activate (fib_entry_src_t *src,
return (!0);
}
src->rr.fesr_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
src->u.rr.fesr_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix);
ASSERT(FIB_NODE_INDEX_INVALID != src->rr.fesr_cover);
ASSERT(FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover);
cover = fib_entry_get(src->rr.fesr_cover);
cover = fib_entry_get(src->u.rr.fesr_cover);
src->rr.fesr_sibling =
src->u.rr.fesr_sibling =
fib_entry_cover_track(cover, fib_entry_get_index(fib_entry));
/*
@@ -175,11 +177,11 @@ fib_entry_src_rr_deactivate (fib_entry_src_t *src,
/*
* remove the depednecy on the covering entry
*/
if (FIB_NODE_INDEX_INVALID != src->rr.fesr_cover)
if (FIB_NODE_INDEX_INVALID != src->u.rr.fesr_cover)
{
cover = fib_entry_get(src->rr.fesr_cover);
fib_entry_cover_untrack(cover, src->rr.fesr_sibling);
src->rr.fesr_cover = FIB_NODE_INDEX_INVALID;
cover = fib_entry_get(src->u.rr.fesr_cover);
fib_entry_cover_untrack(cover, src->u.rr.fesr_sibling);
src->u.rr.fesr_cover = FIB_NODE_INDEX_INVALID;
}
fib_path_list_unlock(src->fes_pl);
@@ -187,7 +189,7 @@ fib_entry_src_rr_deactivate (fib_entry_src_t *src,
src->fes_entry_flags = FIB_ENTRY_FLAG_NONE;
}
static fib_entry_src_cover_res_t
fib_entry_src_cover_res_t
fib_entry_src_rr_cover_change (fib_entry_src_t *src,
const fib_entry_t *fib_entry)
{
@@ -196,7 +198,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
.bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
};
if (FIB_NODE_INDEX_INVALID == src->rr.fesr_cover)
if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
{
/*
* the source may be added, but it is not active
@@ -210,7 +212,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
* entry inserted benaeth it. That does not necessarily mean that this
* entry is covered by the new prefix. check that
*/
if (src->rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
if (src->u.rr.fesr_cover != fib_table_get_less_specific(fib_entry->fe_fib_index,
&fib_entry->fe_prefix))
{
fib_entry_src_rr_deactivate(src, fib_entry);
@@ -230,7 +232,7 @@ fib_entry_src_rr_cover_change (fib_entry_src_t *src,
* This entry's cover has updated its forwarding info. This entry
* will need to re-inheret.
*/
static fib_entry_src_cover_res_t
fib_entry_src_cover_res_t
fib_entry_src_rr_cover_update (fib_entry_src_t *src,
const fib_entry_t *fib_entry)
{
@@ -241,7 +243,7 @@ fib_entry_src_rr_cover_update (fib_entry_src_t *src,
fib_node_index_t old_path_list;
fib_entry_t *cover;
if (FIB_NODE_INDEX_INVALID == src->rr.fesr_cover)
if (FIB_NODE_INDEX_INVALID == src->u.rr.fesr_cover)
{
/*
* the source may be added, but it is not active
@@ -250,7 +252,7 @@ fib_entry_src_rr_cover_update (fib_entry_src_t *src,
return (res);
}
cover = fib_entry_get(src->rr.fesr_cover);
cover = fib_entry_get(src->u.rr.fesr_cover);
old_path_list = src->fes_pl;
/*
@@ -280,7 +282,7 @@ static u8*
fib_entry_src_rr_format (fib_entry_src_t *src,
u8* s)
{
return (format(s, " cover:%d", src->rr.fesr_cover));
return (format(s, " cover:%d", src->u.rr.fesr_cover));
}
const static fib_entry_src_vft_t rr_src_vft = {
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2016 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __FIB_ENTRY_SRC_RR_H__
#define __FIB_ENTRY_SRC_RR_H__
#include "fib_entry_src.h"
/*
* the flags that an RR sourced entry can inherit from its cover
*/
#define FIB_ENTRY_FLAGS_RR_INHERITED (FIB_ENTRY_FLAG_CONNECTED | \
FIB_ENTRY_FLAG_ATTACHED)
/*
* fib_entry_src_rr_resolve_via_connected
*
* Resolve via a connected cover.
*/
void
fib_entry_src_rr_resolve_via_connected (fib_entry_src_t *src,
const fib_entry_t *fib_entry,
const fib_entry_t *cover);
/*
* use the path-list of the cover, unless it would form a loop.
* that is unless the cover is via this entry.
* If a loop were to form it would be a 1 level loop (i.e. X via X),
* and there would be 2 locks on the path-list; one since its used
* by the cover, and 1 from here. The first lock will go when the
* cover is removed, the second, and last, when the covered walk
* occurs during the cover's removel - this is not a place where
* we can handle last lock gone.
* In short, don't let the loop form. The usual rules of 'we must
* let it form so we know when it breaks' don't apply here, since
* the loop will break when the cover changes, and this function
* will be called again when that happens.
*/
void
fib_entry_src_rr_use_covers_pl (fib_entry_src_t *src,
const fib_entry_t *fib_entry,
const fib_entry_t *cover);
/*
* fib_entry_src_rr_cover_update
*
* This entry's cover has changed. This entry
* will need to re-inheret.
*/
fib_entry_src_cover_res_t
fib_entry_src_rr_cover_change (fib_entry_src_t *src,
const fib_entry_t *fib_entry);
/*
* fib_entry_src_rr_cover_update
*
* This entry's cover has updated its forwarding info. This entry
* will need to re-inheret.
*/
fib_entry_src_cover_res_t
fib_entry_src_rr_cover_update (fib_entry_src_t *src,
const fib_entry_t *fib_entry);
#endif
+2 -5
View File
@@ -1011,14 +1011,12 @@ fib_path_list_path_remove (fib_node_index_t path_list_index,
fib_node_index_t
fib_path_list_copy_and_path_remove (fib_node_index_t orig_path_list_index,
fib_path_list_flags_t flags,
const fib_route_path_t *rpaths)
const fib_route_path_t *rpath)
{
fib_node_index_t path_index, *orig_path_index, path_list_index, tmp_path_index;
fib_path_list_t *path_list, *orig_path_list;
fib_node_index_t pi;
ASSERT(1 == vec_len(rpaths));
path_list = fib_path_list_alloc(&path_list_index);
flags = fib_path_list_flags_fixup(flags);
@@ -1041,8 +1039,7 @@ fib_path_list_copy_and_path_remove (fib_node_index_t orig_path_list_index,
* create a representation of the path to be removed, so it
* can be used as a comparison object during the copy.
*/
tmp_path_index = fib_path_create(path_list_index,
rpaths);
tmp_path_index = fib_path_create(path_list_index, rpath);
vec_foreach (orig_path_index, orig_path_list->fpl_paths)
{
+4018 -3576
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -35,6 +35,7 @@ typedef enum fib_test_lb_bucket_type_t_ {
FT_LB_BIER_TABLE,
FT_LB_BIER_FMASK,
FT_LB_DROP,
FT_LB_PUNT,
FT_LB_ADJ,
} fib_test_lb_bucket_type_t;
+2 -1
View File
@@ -37,7 +37,8 @@ typeonly define fib_mpls_label
@param is_source_lookup - The the path is a deaggregate path (i.e. a lookup
in another table) is the lookup on the packet's
source address or destination.
@param afi - the afi of the next hop, IP46_TYPE_IP4=1, IP46_TYPE_IP6=2
@param afi - dpo_proto_t protocol that describes the next-hop address
@param via_label - The next-hop is a resolved via a local label
@param next_hop[16] - the next hop address
@param next_hop_id - Used when the path resolves via an object
that has a unique identifier. e.g. the UDP

Some files were not shown because too many files have changed in this diff Show More