diff options
author | Neale Ranns <nranns@cisco.com> | 2018-12-06 13:46:49 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-12-07 15:09:37 +0000 |
commit | 521a8d7df423a0b5aaf259d49ca9230705bc25ee (patch) | |
tree | 12559229002f31b289adb15460b967a3d10900f3 /src/vnet/adj/adj.h | |
parent | ab86f86e7c29393fa1da81b5f86296bd5fcb7420 (diff) |
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>
Diffstat (limited to 'src/vnet/adj/adj.h')
-rw-r--r-- | src/vnet/adj/adj.h | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/src/vnet/adj/adj.h b/src/vnet/adj/adj.h index 18a2e1ddbbb..fb3dc368db0 100644 --- a/src/vnet/adj/adj.h +++ b/src/vnet/adj/adj.h @@ -157,14 +157,12 @@ typedef void (*adj_midchain_fixup_t) (vlib_main_t * vm, /** * @brief Flags on an IP adjacency */ -typedef enum ip_adjacency_flags_t_ +typedef enum adj_attr_t_ { - ADJ_FLAG_NONE = 0, - /** * Currently a sync walk is active. Used to prevent re-entrant walking */ - ADJ_FLAG_SYNC_WALK_ACTIVE = (1 << 0), + ADJ_ATTR_SYNC_WALK_ACTIVE = 0, /** * Packets TX through the midchain do not increment the interface @@ -173,10 +171,48 @@ typedef enum ip_adjacency_flags_t_ * the packet will have traversed the interface's TX node, and hence have * been counted, before it traverses ths midchain */ - ADJ_FLAG_MIDCHAIN_NO_COUNT = (1 << 1), + ADJ_ATTR_MIDCHAIN_NO_COUNT, + /** + * When stacking midchains on a fib-entry extract the choice from the + * load-balance returned based on an IP hash of the adj's rewrite + */ + ADJ_ATTR_MIDCHAIN_IP_STACK, + /** + * If the midchain were to stack on its FIB entry a loop would form. + */ + ADJ_ATTR_MIDCHAIN_LOOPED, +} adj_attr_t; + +#define ADJ_ATTR_NAMES { \ + [ADJ_ATTR_SYNC_WALK_ACTIVE] = "walk-active", \ + [ADJ_ATTR_MIDCHAIN_NO_COUNT] = "midchain-no-count", \ + [ADJ_ATTR_MIDCHAIN_IP_STACK] = "midchain-ip-stack", \ + [ADJ_ATTR_MIDCHAIN_LOOPED] = "midchain-looped", \ +} + +#define FOR_EACH_ADJ_ATTR(_attr) \ + for (_attr = ADJ_ATTR_SYNC_WALK_ACTIVE; \ + _attr <= ADJ_ATTR_MIDCHAIN_LOOPED; \ + _attr++) + +/** + * @brief Flags on an IP adjacency + */ +typedef enum adj_flags_t_ +{ + ADJ_FLAG_NONE = 0, + ADJ_FLAG_SYNC_WALK_ACTIVE = (1 << ADJ_ATTR_SYNC_WALK_ACTIVE), + ADJ_FLAG_MIDCHAIN_NO_COUNT = (1 << ADJ_ATTR_MIDCHAIN_NO_COUNT), + ADJ_FLAG_MIDCHAIN_IP_STACK = (1 << ADJ_ATTR_MIDCHAIN_IP_STACK), + ADJ_FLAG_MIDCHAIN_LOOPED = (1 << ADJ_ATTR_MIDCHAIN_LOOPED), } __attribute__ ((packed)) adj_flags_t; /** + * @brief Format adjacency flags + */ +extern u8* format_adj_flags(u8 * s, va_list * args); + +/** * @brief IP unicast adjacency. * @note cache aligned. * @@ -257,6 +293,11 @@ typedef struct ip_adjacency_t_ * Fixup data passed back to the client in the fixup function */ const void *fixup_data; + /** + * the FIB entry this midchain resolves through. required for recursive + * loop detection. + */ + fib_node_index_t fei; } midchain; /** * IP_LOOKUP_NEXT_GLEAN @@ -355,6 +396,18 @@ extern const u8* adj_get_rewrite (adj_index_t ai); extern void adj_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable); /** + * @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_recursive_loop_detect (adj_index_t ai, + fib_node_index_t **entry_indicies); + +/** * @brief * The global adjacnecy pool. Exposed for fast/inline data-plane access */ |