/** Multicast Adjacency. */
IP_LOOKUP_NEXT_MCAST,
+ /** Broadcasr Adjacency. */
+ IP_LOOKUP_NEXT_BCAST,
+
/** Multicast Midchain Adjacency. An Adjacency for sending macst packets
* on a tunnel/virtual interface */
IP_LOOKUP_NEXT_MCAST_MIDCHAIN,
[IP_LOOKUP_NEXT_GLEAN] = "ip4-glean", \
[IP_LOOKUP_NEXT_REWRITE] = "ip4-rewrite", \
[IP_LOOKUP_NEXT_MCAST] = "ip4-rewrite-mcast", \
+ [IP_LOOKUP_NEXT_BCAST] = "ip4-rewrite-bcast", \
[IP_LOOKUP_NEXT_MIDCHAIN] = "ip4-midchain", \
[IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip4-mcast-midchain", \
[IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error", \
[IP_LOOKUP_NEXT_ARP] = "ip6-discover-neighbor", \
[IP_LOOKUP_NEXT_GLEAN] = "ip6-glean", \
[IP_LOOKUP_NEXT_REWRITE] = "ip6-rewrite", \
+ [IP_LOOKUP_NEXT_BCAST] = "ip6-rewrite-bcast", \
[IP_LOOKUP_NEXT_MCAST] = "ip6-rewrite-mcast", \
[IP_LOOKUP_NEXT_MIDCHAIN] = "ip6-midchain", \
[IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip6-mcast-midchain", \
[IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop", \
}
+/**
+ * The special broadcast address (to construct a broadcast adjacency
+ */
+extern const ip46_address_t ADJ_BCAST_ADDR;
+
/**
* Forward delcartion
*/
/**
* @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
* 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.
* 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
extern void adj_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable);
/**
- * @brief Notify the adjacency subsystem that the MTU settings for
- * an HW interface have changed
+ * @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 void adj_mtu_update (u32 hw_if_index);
+extern int adj_recursive_loop_detect (adj_index_t ai,
+ fib_node_index_t **entry_indicies);
/**
* @brief