#ifndef __FIB_TYPES_H__
#define __FIB_TYPES_H__
+#include <stdbool.h>
#include <vlib/vlib.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/mpls/packet.h>
#include <vnet/dpo/dpo.h>
+#include <vnet/bier/bier_types.h>
/**
* A typedef of a node index.
* Protocol Type. packed so it consumes a u8 only
*/
typedef enum fib_protocol_t_ {
- FIB_PROTOCOL_IP4 = 0,
- FIB_PROTOCOL_IP6,
- FIB_PROTOCOL_MPLS,
+ FIB_PROTOCOL_IP4 = DPO_PROTO_IP4,
+ FIB_PROTOCOL_IP6 = DPO_PROTO_IP6,
+ FIB_PROTOCOL_MPLS = DPO_PROTO_MPLS,
} __attribute__ ((packed)) fib_protocol_t;
#define FIB_PROTOCOLS { \
*/
#define FIB_PROTOCOL_MAX (FIB_PROTOCOL_MPLS + 1)
+/**
+ * Definition outside of enum so it does not need to be included in non-defaulted
+ * switch statements
+ */
+#define FIB_PROTOCOL_IP_MAX (FIB_PROTOCOL_IP6 + 1)
+
/**
* Not part of the enum so it does not have to be handled in switch statements
*/
_item <= FIB_PROTOCOL_IP6; \
_item++)
+/**
+ * @brief Convert from boolean is_ip6 to FIB protocol.
+ * Drop MPLS on the floor in favor of IPv4.
+ */
+static inline fib_protocol_t
+fib_ip_proto(bool is_ip6)
+{
+ return (is_ip6) ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
+}
+
/**
* @brief Convert from a protocol to a link type
*/
* MPLS packets
*/
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
+ /**
+ * Contribute an object that is to be used to forward BIER packets.
+ */
+ FIB_FORW_CHAIN_TYPE_BIER,
/**
* Contribute an object that is to be used to forward end-of-stack
* MPLS packets. This is a convenient ID for clients. A real EOS chain
#define FIB_FORW_CHAINS { \
[FIB_FORW_CHAIN_TYPE_ETHERNET] = "ethernet", \
+ [FIB_FORW_CHAIN_TYPE_BIER] = "bier", \
[FIB_FORW_CHAIN_TYPE_UNICAST_IP4] = "unicast-ip4", \
[FIB_FORW_CHAIN_TYPE_UNICAST_IP6] = "unicast-ip6", \
[FIB_FORW_CHAIN_TYPE_MCAST_IP4] = "multicast-ip4", \
_item++)
/**
- * @brief Convert from a chain type to the adjacencies link type
+ * @brief Convert from a chain type to the adjacency's link type
*/
extern vnet_link_t fib_forw_chain_type_to_link_type(fib_forward_chain_type_t fct);
+/**
+ * @brief Convert from a adjacency's link type to chain type
+ */
+extern fib_forward_chain_type_t fib_forw_chain_type_from_link_type(vnet_link_t lt);
+
/**
* @brief Convert from a payload-protocol to a chain type.
*/
extern dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto);
extern fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto);
+/**
+ * Convert from BIER next-hop proto to FIB proto
+ */
+extern fib_protocol_t bier_hdr_proto_to_fib(bier_hdr_proto_id_t bproto);
+
/**
* Enurmeration of special path/entry types
*/
for (_item = FIB_TYPE_SPEICAL_FIRST; \
_item <= FIB_SPEICAL_TYPE_LAST; _item++)
-extern u8 * format_fib_protocol(u8 * s, va_list ap);
-extern u8 * format_vnet_link(u8 *s, va_list ap);
+extern u8 * format_fib_protocol(u8 * s, va_list *ap);
+extern u8 * format_vnet_link(u8 *s, va_list *ap);
/**
* Path flags from the control plane
* A local path with a RPF-ID => multicast traffic
*/
FIB_ROUTE_PATH_RPF_ID = (1 << 7),
+ /**
+ * A deag path using the packet's source not destination address.
+ */
+ FIB_ROUTE_PATH_SOURCE_LOOKUP = (1 << 8),
+ /**
+ * A path via a UDP encap object.
+ */
+ FIB_ROUTE_PATH_UDP_ENCAP = (1 << 9),
+ /**
+ * A path that resolves via a BIER F-Mask
+ */
+ FIB_ROUTE_PATH_BIER_FMASK = (1 << 10),
+ /**
+ * A path that resolves via a BIER [ECMP] Table
+ */
+ FIB_ROUTE_PATH_BIER_TABLE = (1 << 11),
+ /**
+ * A path that resolves via a BIER impostion object
+ */
+ FIB_ROUTE_PATH_BIER_IMP = (1 << 12),
+ /**
+ * A path that resolves via another table
+ */
+ FIB_ROUTE_PATH_DEAG = (1 << 13),
+ /**
+ * A path that resolves via a DVR DPO
+ */
+ FIB_ROUTE_PATH_DVR = (1 << 14),
} fib_route_path_flags_t;
/**
#define MFIB_RPF_ID_NONE (0)
+/**
+ * MPLS LSP mode - only valid at the head and tail
+ */
+typedef enum fib_mpls_lsp_mode_t_
+{
+ /**
+ * Pipe Mode - the default.
+ * TTL and DSCP markings are not carried between the layers
+ */
+ FIB_MPLS_LSP_MODE_PIPE,
+ /**
+ * Uniform mode.
+ * TTL and DSCP are copied between the layers
+ */
+ FIB_MPLS_LSP_MODE_UNIFORM,
+} __attribute__((packed)) fib_mpls_lsp_mode_t;
+
+#define FIB_MPLS_LSP_MODES { \
+ [FIB_MPLS_LSP_MODE_PIPE] = "pipe", \
+ [FIB_MPLS_LSP_MODE_UNIFORM] = "uniform", \
+}
+
+/**
+ * Format an LSP mode type
+ */
+extern u8 * format_fib_mpls_lsp_mode(u8 *s, va_list *ap);
+
+/**
+ * Configuration for each label value in the output-stack
+ */
+typedef struct fib_mpls_label_t_
+{
+ /**
+ * The label value
+ */
+ mpls_label_t fml_value;
+
+ /**
+ * The LSP mode
+ */
+ fib_mpls_lsp_mode_t fml_mode;
+
+ /**
+ * TTL. valid only at imposition.
+ */
+ u8 fml_ttl;
+
+ /**
+ * EXP bits; valid only at imposition.
+ */
+ u8 fml_exp;
+} fib_mpls_label_t;
+
+/**
+ * Format an MPLS label
+ */
+extern u8 * format_fib_mpls_label(u8 *s, va_list *ap);
+
/**
* @brief
* A representation of a path as described by a route producer.
* The protocol of the address below. We need this since the all
* zeros address is ambiguous.
*/
- fib_protocol_t frp_proto;
+ dpo_proto_t frp_proto;
union {
- /**
- * The next-hop address.
- * Will be NULL for attached paths.
- * Will be all zeros for attached-next-hop paths on a p2p interface
- * Will be all zeros for a deag path.
- */
- ip46_address_t frp_addr;
-
struct {
+ union {
+ /**
+ * The next-hop address.
+ * Will be NULL for attached paths.
+ * Will be all zeros for attached-next-hop paths on a p2p interface
+ * Will be all zeros for a deag path.
+ */
+ ip46_address_t frp_addr;
+
+ struct {
+ /**
+ * The MPLS local Label to reursively resolve through.
+ * This is valid when the path type is MPLS.
+ */
+ mpls_label_t frp_local_label;
+ /**
+ * EOS bit for the resolving label
+ */
+ mpls_eos_bit_t frp_eos;
+ };
+ };
+ union {
+ /**
+ * The interface.
+ * Will be invalid for recursive paths.
+ */
+ u32 frp_sw_if_index;
+ /**
+ * The RPF-ID
+ */
+ fib_rpf_id_t frp_rpf_id;
+ };
+ union {
+ /**
+ * The FIB index to lookup the nexthop
+ * Only valid for recursive paths.
+ */
+ u32 frp_fib_index;
+ /**
+ * The BIER table to resolve the fmask in
+ */
+ u32 frp_bier_fib_index;
+ };
/**
- * The MPLS local Label to reursively resolve through.
- * This is valid when the path type is MPLS.
+ * The outgoing MPLS label Stack. NULL implies no label.
*/
- mpls_label_t frp_local_label;
- /**
- * EOS bit for the resolving label
- */
- mpls_eos_bit_t frp_eos;
+ fib_mpls_label_t *frp_label_stack;
};
- };
- union {
/**
- * The interface.
- * Will be invalid for recursive paths.
+ * A path that resolves via a BIER Table.
+ * This would be for a MPLS label at a BIER midpoint or tail
*/
- u32 frp_sw_if_index;
+ bier_table_id_t frp_bier_tbl;
+
+ /**
+ * A path via a BIER imposition object.
+ * Present in an mfib path list
+ */
+ index_t frp_bier_imp;
+
+ /**
+ * UDP encap ID
+ */
+ u32 frp_udp_encap_id;
+
/**
- * The RPF-ID
+ * Resolving via a BIER Fmask
*/
- fib_rpf_id_t frp_rpf_id;
+ index_t frp_bier_fmask;
};
- /**
- * The FIB index to lookup the nexthop
- * Only valid for recursive paths.
- */
- u32 frp_fib_index;
/**
* [un]equal cost path weight
*/
- u16 frp_weight;
+ u8 frp_weight;
/**
* A path preference. 0 is the best.
* Only paths of the best preference, that are 'up', are considered
* for forwarding.
*/
- u16 frp_preference;
+ u8 frp_preference;
/**
* flags on the path
*/
fib_route_path_flags_t frp_flags;
- /**
- * The outgoing MPLS label Stack. NULL implies no label.
- */
- mpls_label_t *frp_label_stack;
} fib_route_path_t;
+/**
+ * Unformat a fib_route_path_t from CLI input
+ */
+extern uword unformat_fib_route_path(unformat_input_t * input, va_list * args);
+
+/**
+ * A help string to list the FIB path options
+ */
+#define FIB_ROUTE_PATH_HELP "[next-hop-address] [next-hop-interface] [next-hop-table <value>] [weight <value>] [preference <value>] [udp-encap-id <value>] [ip4-lookup-in-table <value>] [ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] [resolve-via-host] [resolve-via-connected] [rx-ip4 <interface>] [out-labels <value value value>]"
+
/**
* @brief
* A representation of a fib path for fib_path_encode to convey the information to the caller