summaryrefslogtreecommitdiffstats
path: root/src/vnet/fib/fib_path_list.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-05-18 03:03:22 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2017-05-23 09:48:52 +0000
commit8142499cd1cb3b8d0168d0e6cf5309c5b4813cc4 (patch)
treeb6191c8b7417aa3a6865ec8b90837d852b90b539 /src/vnet/fib/fib_path_list.c
parentf3b53643e87e7521c57cccc157385d2fa4bd0d80 (diff)
ARP/ND entries for the same address on different interfaces (VPP-848)
there are, intentionally, no validation checks in the ARP/ND code to prevent an ARP/ND entry from being installed for an address that is not local to the interface's sub-net. This is ok, since the adjacency/FIB code is designed to handle this case using the 'refinement' criteria - i.e. only installing a FIB entry for the address if the address 'refines' (i.e. is more specific than) the interface's sub-net. However, the refinement criteria currently operates on the FIB entry's prefix (which is a /32, so on the address) and not on the next-hop in the path. So, enter multiple ARP entries for the same address on different links, and this refinement criteria uses only the last added path, and so will remove the FIB entry should the ARP entries be added in the 'wrong' order. This fix updates the refinement criteria to work on each path of the FIB entry. The entry is installed if one of the paths refines the covers and only paths refining the cover contribute forwarding. Per-path refinement checks are stored in path-extensions. The patch is rather large as path-extension, which were previously used only for out-going MPLS labels, have been generalized. Change-Id: I00be359148cb948c32c52109e832a70537a7920a Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/fib/fib_path_list.c')
-rw-r--r--src/vnet/fib/fib_path_list.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/vnet/fib/fib_path_list.c b/src/vnet/fib/fib_path_list.c
index 64917f95107..3e4c3333a08 100644
--- a/src/vnet/fib/fib_path_list.c
+++ b/src/vnet/fib/fib_path_list.c
@@ -914,21 +914,32 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index,
* If we find one then we can return the existing one and destroy the
* new one just created.
*/
- exist_path_list_index = fib_path_list_db_find(path_list);
- if (FIB_NODE_INDEX_INVALID != exist_path_list_index)
+ if (path_list->fpl_flags & FIB_PATH_LIST_FLAG_SHARED)
{
- fib_path_list_destroy(path_list);
+ exist_path_list_index = fib_path_list_db_find(path_list);
+ if (FIB_NODE_INDEX_INVALID != exist_path_list_index)
+ {
+ fib_path_list_destroy(path_list);
- path_list_index = exist_path_list_index;
+ path_list_index = exist_path_list_index;
+ }
+ else
+ {
+ /*
+ * if there was not a matching path-list, then this
+ * new one will need inserting into the DB and resolving.
+ */
+ fib_path_list_db_insert(path_list_index);
+
+ path_list = fib_path_list_resolve(path_list);
+ }
}
else
{
/*
- * if there was not a matching path-list, then this
- * new one will need inserting into the DB and resolving.
+ * no shared path list requested. resolve and use the one
+ * just created.
*/
- fib_path_list_db_insert(path_list_index);
-
path_list = fib_path_list_resolve(path_list);
}
@@ -1289,7 +1300,9 @@ fib_path_list_walk (fib_node_index_t path_list_index,
vec_foreach(path_index, path_list->fpl_paths)
{
- if (!func(path_list_index, *path_index, ctx))
+ if (FIB_PATH_LIST_WALK_STOP == func(path_list_index,
+ *path_index,
+ ctx))
break;
}
}