summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/fib/fib_entry_src.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2016-10-03 13:05:48 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2016-10-07 21:32:24 +0000
commit3ee44040c66cbe47ff292ac7fb0badccbe2afe6d (patch)
treea52a4dd0750467845f237ee5e4e88aa95ea11bab /vnet/vnet/fib/fib_entry_src.c
parent4a7e58bf481adb843707eec4a81213776a6d5212 (diff)
unicast RPF for FIB2.0
In a heirarchical FIB performing a unicast RPF check would require the traversal of the data-plane graph to seek out all the adjacency objects and then read those to find their interface. This is not efficient. Instead, for each path-list we construct a list of unique input interfaces and link this uRPF-list against the entry in the prefix table. In the data-plane the uRPF list can be retrieved from the load-balance lookup result and the RPF check is a simple and efficient walk across the minimal interface list. The uRPF-list is maintained as the routing heirarchy changes, in a similar way to the data-plane object graph. We also provide a knob to allow an arbitrary prefix to pass the loose check. Change-Id: Ie7c0ae3c4483ef467cfd5b136ee0315ff98ec15b Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'vnet/vnet/fib/fib_entry_src.c')
-rw-r--r--vnet/vnet/fib/fib_entry_src.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/vnet/vnet/fib/fib_entry_src.c b/vnet/vnet/fib/fib_entry_src.c
index 0bca17dd884..6107e3e19cd 100644
--- a/vnet/vnet/fib/fib_entry_src.c
+++ b/vnet/vnet/fib/fib_entry_src.c
@@ -18,9 +18,10 @@
#include <vnet/dpo/mpls_label_dpo.h>
#include <vnet/dpo/drop_dpo.h>
-#include "fib_entry_src.h"
-#include "fib_table.h"
-#include "fib_path_ext.h"
+#include <vnet/fib/fib_entry_src.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_path_ext.h>
+#include <vnet/fib/fib_urpf_list.h>
/*
* per-source type vft
@@ -368,6 +369,33 @@ fib_entry_src_mk_lb (fib_entry_t *fib_entry,
load_balance_multipath_update(dpo_lb,
ctx.next_hops,
fib_entry_calc_lb_flags(&ctx));
+
+ /*
+ * if this entry is sourced by the uRPF-exempt source then we
+ * append the always present local0 interface (index 0) to the
+ * uRPF list so it is not empty. that way packets pass the loose check.
+ */
+ index_t ui = fib_path_list_get_urpf(esrc->fes_pl);
+
+ if (fib_entry_is_sourced(fib_entry_get_index(fib_entry),
+ FIB_SOURCE_URPF_EXEMPT) &&
+ (0 == fib_urpf_check_size(ui)))
+ {
+ /*
+ * The uRPF list we get from the path-list is shared by all
+ * other users of the list, but the uRPF exemption applies
+ * only to this prefix. So we need our own list.
+ */
+ ui = fib_urpf_list_alloc_and_lock();
+ fib_urpf_list_append(ui, 0);
+ fib_urpf_list_bake(ui);
+ load_balance_set_urpf(dpo_lb->dpoi_index, ui);
+ fib_urpf_list_unlock(ui);
+ }
+ else
+ {
+ load_balance_set_urpf(dpo_lb->dpoi_index, ui);
+ }
}
void
@@ -425,17 +453,13 @@ fib_entry_src_action_uninstall (fib_entry_t *fib_entry)
fct = fib_entry_get_default_chain_type(fib_entry);
/*
- * uninstall the forwarding chain for the given source from the
- * forwarding tables
+ * uninstall the forwarding chain from the forwarding tables
*/
FIB_ENTRY_DBG(fib_entry, "uninstall: %d",
fib_entry->fe_adj_index);
if (dpo_id_is_valid(&fib_entry->fe_lb[fct]))
{
- /* fib_forward_chain_type_t fct; */
- /* fib_path_ext_t *path_ext; */
-
fib_table_fwding_dpo_remove(
fib_entry->fe_fib_index,
&fib_entry->fe_prefix,