#include <vnet/adj/adj.h>
-/**
- * @brief Flags controlling the midchain adjacency
- */
-typedef enum adj_midchain_flag_t_
-{
- /**
- * No flags
- */
- ADJ_MIDCHAIN_FLAG_NONE = 0,
-
- /**
- * Packets TX through the midchain do not increment the interface
- * counters. This should be used when the adj is associated with an L2
- * interface and that L2 interface is in a bridege domain. In that case
- * the packet will have traversed the interface's TX node, and hence have
- * been counted, before it traverses ths midchain
- */
- ADJ_MIDCHAIN_FLAG_NO_COUNT = (1 << 0),
-} adj_midchain_flag_t;
-
/**
* @brief
* Convert an existing neighbour adjacency into a midchain
* @param adj_index
* The index of the neighbour adjacency.
*
- * @param post_rewrite_node
- * The VLIB graph node that provides the post-encap fixup.
- * where 'fixup' is e.g., correcting chksum, length, etc.
+ * @param fixup
+ * The function that will be invoked at paket switch time to 'fixup'
+ * the rewrite applied with necessary per-packet info (i.e. length, checksums).
+ * @param fixup_data
+ * Context data set by the caller that is provided as an argument in the
+ * fixup function.
+ *
+ * @param flags
+ * Flags controlling the adjacency behaviour
*
* @param rewrite
* The rewrite.
*/
extern void adj_nbr_midchain_update_rewrite(adj_index_t adj_index,
adj_midchain_fixup_t fixup,
- adj_midchain_flag_t flags,
+ const void *fixup_data,
+ adj_flags_t flags,
u8 *rewrite);
+/**
+ * @brief
+ * Return the adjacency's next node to its default value
+ *
+ * @param adj_index
+ * The index of the neighbour adjacency.
+ */
+extern void adj_nbr_midchain_reset_next_node(adj_index_t adj_index);
+
+/**
+ * @brief
+ * Update the VLIB node to which packets are sent post processing
+ *
+ * @param adj_index
+ * The index of the neighbour adjacency.
+ *
+ * @param node node-index to send to
+ */
+extern void adj_nbr_midchain_update_next_node(adj_index_t adj_index,
+ u32 node_index);
+
/**
* @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
extern void adj_nbr_midchain_stack(adj_index_t adj_index,
const dpo_id_t *dpo);
+/**
+ * @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 forwarding
+ */
+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
*/
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
*/
extern u8* format_adj_midchain(u8* s, va_list *ap);
+/**
+ * @brief
+ * create/attach a midchain delegate and stack it on the prefix passed
+ * @param ai - the index of the adjacency to stack
+ * @param fib_index - The FIB index of the prefix on which to stack
+ * @param pfx - The prefix on which to stack
+ */
+extern void adj_midchain_delegate_stack(adj_index_t ai,
+ u32 fib_index,
+ const fib_prefix_t *pfx);
+
+/**
+ * @brief restack a midchain delegate
+ */
+extern void adj_midchain_delegate_restack(adj_index_t ai);
+
+/**
+ * @brief unstack a midchain delegate (this stacks it on a drop)
+ */
+extern void adj_midchain_delegate_unstack(adj_index_t ai);
+
+extern u8 adj_is_midchain (adj_index_t ai);
+
#endif