FIB recusrion loop checks traverse midchain adjacencies
if a tunnel's destination address is reachable through the tunnel
(see example config belwo) then search for and detect a recursion
loop and don't stack the adjacency. Otherwise this results in a
nasty surprise.
DBGvpp# loop cre
DBGvpp# set int state loop0 up
DBGvpp# set int ip addr loop0 10.0.0.1/24
DBGvpp# create gre tunnel src 10.0.0.1 dst 1.1.1.1
DBGvpp# set int state gre0 up
DBGvpp# set int unnum gre0 use loop0
DBGvpp# ip route 1.1.1.1/32 via gre0
DBGvpp# sh ip fib 1.1.1.1
ipv4-VRF:0, fib_index:0, flow hash:[src dst sport dport proto ] locks:[src:plugin-hi:2, src:default-route:1, ]
1.1.1.1/32 fib:0 index:11 locks:4 <<< this is entry #11
src:CLI refs:1 entry-flags:attached, src-flags:added,contributing,active,
path-list:[14] locks:2 flags:shared,looped, uPRF-list:12 len:1 itfs:[2, ]
path:[14] pl-index:14 ip4 weight=1 pref=0 attached-nexthop: oper-flags:recursive-loop,resolved, cfg-flags:attached,
1.1.1.1 gre0 (p2p)
[@0]: ipv4 via 0.0.0.0 gre0: mtu:9000 4500000000000000fe2fb0cc0a0000010101010100000800
stacked-on entry:11: <<<< and the midchain forwards via entry #11
[@2]: dpo-drop ip4
src:recursive-resolution refs:1 src-flags:added, cover:-1
forwarding: unicast-ip4-chain
[@0]: dpo-load-balance: [proto:ip4 index:13 buckets:1 uRPF:12 to:[0:0]]
[0] [@6]: ipv4 via 0.0.0.0 gre0: mtu:9000 4500000000000000fe2fb0cc0a0000010101010100000800
stacked-on entry:11:
[@2]: dpo-drop ip4
DBGvpp# sh adj 1
[@1] ipv4 via 0.0.0.0 gre0: mtu:9000 4500000000000000fe2fb0cc0a0000010101010100000800
stacked-on entry:11:
[@2]: dpo-drop ip4
flags:midchain-ip-stack midchain-looped <<<<< this is a loop
counts:[0:0]
locks:4
delegates:
children:
{path:14}
Change-Id: I39b82bd1ea439be4611c88b130d40289fa0c1b59
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/adj/adj_midchain.h b/src/vnet/adj/adj_midchain.h
index 6589231..24fea42 100644
--- a/src/vnet/adj/adj_midchain.h
+++ b/src/vnet/adj/adj_midchain.h
@@ -53,7 +53,8 @@
/**
* @brief
* [re]stack a midchain. 'Stacking' is the act of forming parent-child
- * relationships in the data-plane graph.
+ * relationships in the data-plane graph. Do NOT use this function to
+ * stack on a DPO type that might form a loop.
*
* @param adj_index
* The index of the midchain to stack
@@ -66,6 +67,25 @@
/**
* @brief
+ * [re]stack a midchain. 'Stacking' is the act of forming parent-child
+ * relationships in the data-plane graph. Since function performs recursive
+ * loop detection.
+ *
+ * @param adj_index
+ * The index of the midchain to stack
+ *
+ * @param fei
+ * The FIB entry to stack on
+ *
+ * @param fct
+ * The chain type to use from the fib entry fowarding
+ */
+extern void adj_nbr_midchain_stack_on_fib_entry(adj_index_t adj_index,
+ fib_node_index_t fei,
+ fib_forward_chain_type_t fct);
+
+/**
+ * @brief
* unstack a midchain. This will break the chain between the midchain and
* the next graph section. This is a implemented as stack-on-drop
*
@@ -75,6 +95,18 @@
extern void adj_nbr_midchain_unstack(adj_index_t adj_index);
/**
+ * @brief descend the FIB graph looking for loops
+ *
+ * @param ai
+ * The adj index to traverse
+ *
+ * @param entry_indicies)
+ * A pointer to a vector of FIB entries already visited.
+ */
+extern int adj_ndr_midchain_recursive_loop_detect(adj_index_t ai,
+ fib_node_index_t **entry_indicies);
+
+/**
* @brief
* Module initialisation
*/