aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/fib/fib_path.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2016-11-21 12:25:22 +0000
committerDamjan Marion <dmarion.lists@gmail.com>2016-11-21 14:18:09 +0000
commit8b37b8732d5f9883ab594fc0ba2b5be21c27c4fd (patch)
tree5cf5accc899d67e874fecdb14150e1bacdec211e /vnet/vnet/fib/fib_path.c
parentc008ee186b13a1246f265372679f5a80970387b5 (diff)
Convergence Improvements
addressing convergence times when interface is shut. 1) prioritise the registered callback handlers. Add FIB convergence handler as high priority 2) hook the FIB convergence call-back into HW link down. 3) don't schedule a walk of a FIB node if it has no children 4) Checks at fib_path_t to prevent unnecessary walks, that it prevent the same information propagting the graph multiple times. Change-Id: I406966b50f31d77c221821b8649776d66655194c Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'vnet/vnet/fib/fib_path.c')
-rw-r--r--vnet/vnet/fib/fib_path.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/vnet/vnet/fib/fib_path.c b/vnet/vnet/fib/fib_path.c
index 5796539b19a..988f689b102 100644
--- a/vnet/vnet/fib/fib_path.c
+++ b/vnet/vnet/fib/fib_path.c
@@ -787,10 +787,24 @@ FIXME comment
*/
if (FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason)
{
+ if (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED)
+ {
+ /*
+ * alreday resolved. no need to walk back again
+ */
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+ }
path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
}
if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason)
{
+ if (!(path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED))
+ {
+ /*
+ * alreday unresolved. no need to walk back again
+ */
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+ }
path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
}
if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason)
@@ -809,10 +823,14 @@ FIXME comment
/*
* restack the DPO to pick up the correct DPO sub-type
*/
+ uword if_is_up;
adj_index_t ai;
- if (vnet_sw_interface_is_admin_up(vnet_get_main(),
- path->attached_next_hop.fp_interface))
+ if_is_up = vnet_sw_interface_is_admin_up(
+ vnet_get_main(),
+ path->attached_next_hop.fp_interface);
+
+ if (if_is_up)
{
path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
}
@@ -825,9 +843,28 @@ FIXME comment
fib_proto_to_dpo(path->fp_nh_proto),
ai);
adj_unlock(ai);
+
+ if (!if_is_up)
+ {
+ /*
+ * If the interface is not up there is no reason to walk
+ * back to children. if we did they would only evalute
+ * that this path is unresolved and hence it would
+ * not contribute the adjacency - so it would be wasted
+ * CPU time.
+ */
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+ }
}
if (FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason)
{
+ if (!(path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED))
+ {
+ /*
+ * alreday unresolved. no need to walk back again
+ */
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+ }
/*
* the adj has gone down. the path is no longer resolved.
*/