X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Fdpo.h;h=ee4990d005825b82bfda895614c0dbf4672ab723;hb=0ebbbfc3c50361dbe8556f14f152613689448812;hp=5aa4e2d2165ebf5fed57ed5ea845415160be0bfc;hpb=0f26c5a0138ac86d7ebd197c31a09d8d624c35fe;p=vpp.git diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h index 5aa4e2d2165..ee4990d0058 100644 --- a/src/vnet/dpo/dpo.h +++ b/src/vnet/dpo/dpo.h @@ -16,7 +16,7 @@ * @brief * A Data-Path Object is an object that represents actions that are * applied to packets are they are switched through VPP's data-path. - * + * * The DPO can be considered to be like is a base class that is specialised * by other objects to provide concreate actions * @@ -59,14 +59,11 @@ typedef u32 index_t; */ typedef enum dpo_proto_t_ { -#if CLIB_DEBUG > 0 - DPO_PROTO_IP4 = 1, -#else DPO_PROTO_IP4 = 0, -#endif DPO_PROTO_IP6, - DPO_PROTO_ETHERNET, DPO_PROTO_MPLS, + DPO_PROTO_ETHERNET, + DPO_PROTO_BIER, DPO_PROTO_NSH, } __attribute__((packed)) dpo_proto_t; @@ -79,6 +76,7 @@ typedef enum dpo_proto_t_ [DPO_PROTO_ETHERNET] = "ethernet", \ [DPO_PROTO_MPLS] = "mpls", \ [DPO_PROTO_NSH] = "nsh", \ + [DPO_PROTO_BIER] = "bier", \ } #define FOR_EACH_DPO_PROTO(_proto) \ @@ -113,10 +111,20 @@ typedef enum dpo_type_t_ { DPO_LOOKUP, DPO_LISP_CP, DPO_CLASSIFY, - DPO_MPLS_LABEL, - DPO_MPLS_DISPOSITION, + DPO_MPLS_DISPOSITION_PIPE, + DPO_MPLS_DISPOSITION_UNIFORM, DPO_MFIB_ENTRY, - DPO_INTERFACE, + DPO_INTERFACE_RX, + DPO_INTERFACE_TX, + DPO_DVR, + DPO_L3_PROXY, + DPO_BIER_TABLE, + DPO_BIER_FMASK, + DPO_BIER_IMP, + DPO_BIER_DISP_TABLE, + DPO_BIER_DISP_ENTRY, + DPO_IP6_LL, + DPO_PW_CW, DPO_LAST, } __attribute__((packed)) dpo_type_t; @@ -139,10 +147,20 @@ typedef enum dpo_type_t_ { [DPO_REPLICATE] = "dpo-replicate", \ [DPO_LISP_CP] = "dpo-lisp-cp", \ [DPO_CLASSIFY] = "dpo-classify", \ - [DPO_MPLS_LABEL] = "dpo-mpls-label", \ - [DPO_MPLS_DISPOSITION] = "dpo-mpls-diposition", \ - [DPO_MFIB_ENTRY] = "dpo-mfib_entry", \ - [DPO_INTERFACE] = "dpo-interface" \ + [DPO_MPLS_DISPOSITION_PIPE] = "dpo-mpls-diposition-pipe", \ + [DPO_MPLS_DISPOSITION_UNIFORM] = "dpo-mpls-diposition-uniform", \ + [DPO_MFIB_ENTRY] = "dpo-mfib-entry", \ + [DPO_INTERFACE_RX] = "dpo-interface-rx", \ + [DPO_INTERFACE_TX] = "dpo-interface-tx", \ + [DPO_DVR] = "dpo-dvr", \ + [DPO_L3_PROXY] = "dpo-l3-proxy", \ + [DPO_BIER_TABLE] = "bier-table", \ + [DPO_BIER_FMASK] = "bier-fmask", \ + [DPO_BIER_IMP] = "bier-imposition", \ + [DPO_BIER_DISP_ENTRY] = "bier-disp-entry", \ + [DPO_BIER_DISP_TABLE] = "bier-disp-table", \ + [DPO_IP6_LL] = "ip6-link-local", \ + [DPO_PW_CW] = "PW-CW", \ } /** @@ -150,23 +168,28 @@ typedef enum dpo_type_t_ { * instance number/index of objects of that type */ typedef struct dpo_id_t_ { - /** - * the type - */ - dpo_type_t dpoi_type; - /** - * the data-path protocol of the type. - */ - dpo_proto_t dpoi_proto; - /** - * The next VLIB node to follow. - */ - u16 dpoi_next_node; - /** - * the index of objects of that type - */ - index_t dpoi_index; -} __attribute__ ((aligned(sizeof(u64)))) dpo_id_t; + union { + struct { + /** + * the type + */ + dpo_type_t dpoi_type; + /** + * the data-path protocol of the type. + */ + dpo_proto_t dpoi_proto; + /** + * The next VLIB node to follow. + */ + u16 dpoi_next_node; + /** + * the index of objects of that type + */ + index_t dpoi_index; + }; + u64 as_u64; + }; +} dpo_id_t; STATIC_ASSERT(sizeof(dpo_id_t) <= sizeof(u64), "DPO ID is greater than sizeof u64 " @@ -208,6 +231,14 @@ extern void dpo_lock(dpo_id_t *dpo); */ extern void dpo_unlock(dpo_id_t *dpo); +/** + * @brief + * Make an interpose DPO from an original + */ +extern void dpo_mk_interpose(const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone); + /** * @brief Set/create a DPO ID * The DPO will be locked. @@ -258,12 +289,12 @@ extern void dpo_copy(dpo_id_t *dst, extern int dpo_is_adj(const dpo_id_t *dpo); /** - * @biref Format a DPO_id_t oject + * @brief Format a DPO_id_t oject */ extern u8 *format_dpo_id(u8 * s, va_list * args); /** - * @biref format a DPO type + * @brief format a DPO type */ extern u8 *format_dpo_type(u8 * s, va_list * args); @@ -272,6 +303,11 @@ extern u8 *format_dpo_type(u8 * s, va_list * args); */ extern u8 *format_dpo_proto(u8 * s, va_list * args); +/** + * @brief format a DPO protocol + */ +extern vnet_link_t dpo_proto_to_link(dpo_proto_t dp); + /** * @brief * Set and stack a DPO. @@ -297,24 +333,34 @@ extern void dpo_stack(dpo_type_t child_type, const dpo_id_t *parent_dpo); /** - * @brief + * @brief * Set and stack a DPO. * The DPO passed is set to the parent DPO and the necessary * VLIB graph arcs are created, from the child_node passed. * * @param child_node - * The VLIB grpah node index to create an arc from to the parent + * The VLIB graph node index to create an arc from to the parent * - * @parem dpo + * @param dpo * This is the DPO to stack and set. * - * @paren parent_dpo + * @param parent_dpo * The parent DPO to stack onto. - */ + */ extern void dpo_stack_from_node(u32 child_node, dpo_id_t *dpo, const dpo_id_t *parent); +/** + * Get a uRPF interface for the DPO + * + * @param dpo + * The DPO from which to get the uRPF interface + * + * @return valid SW interface index or ~0 + */ +extern u32 dpo_get_urpf(const dpo_id_t *dpo); + /** * @brief A lock function registered for a DPO type */ @@ -330,6 +376,30 @@ typedef void (*dpo_unlock_fn_t)(dpo_id_t *dpo); */ typedef void (*dpo_mem_show_t)(void); +/** + * @brief Given a DPO instance return a vector of node indices that + * the type/instance will use. + */ +typedef u32* (*dpo_get_next_node_t)(const dpo_id_t *dpo); + +/** + * @brief Given a DPO instance return an interface that can + * be used in an uRPF check + */ +typedef u32 (*dpo_get_urpf_t)(const dpo_id_t *dpo); + +/** + * @brief Called during FIB interposition when the originally + * registered DPO is used to 'clone' an instance for interposition + * at a particular location in the FIB graph. + * The parent is the next DPO in the chain that the clone will + * be used instead of. The clone may then choose to stack itself + * on the parent. + */ +typedef void (*dpo_mk_interpose_t)(const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone); + /** * @brief A virtual function table regisitered for a DPO type */ @@ -351,6 +421,21 @@ typedef struct dpo_vft_t_ * A show memory usage function */ dpo_mem_show_t dv_mem_show; + /** + * A function to get the next VLIB node given an instance + * of the DPO. If this is null, then the node's name MUST be + * retreiveable from the nodes names array passed in the register + * function + */ + dpo_get_next_node_t dv_get_next_node; + /** + * Get uRPF interface + */ + dpo_get_urpf_t dv_get_urpf; + /** + * Signal on an interposed child that the parent has changed + */ + dpo_mk_interpose_t dv_mk_interpose; } dpo_vft_t; @@ -363,7 +448,7 @@ typedef struct dpo_vft_t_ * (see above). * * @param type - * The type being registered. + * The type being registered. * * @param vft * The virtual function table to register for the type. @@ -392,4 +477,74 @@ extern void dpo_register(dpo_type_t type, extern dpo_type_t dpo_register_new_type(const dpo_vft_t *vft, const char * const * const * nodes); +/** + * @brief Return already stacked up next node index for a given + * child_type/child_proto and parent_type/patent_proto. + * The VLIB graph arc used is taken from the parent and child types + * passed. + * + * @param child_type + * Child DPO type. + * + * @param child_proto + * Child DPO proto + * + * @param parent_type + * Parent DPO type. + * + * @param parent_proto + * Parent DPO proto + * + * @return The VLIB Graph node index + */ +extern u32 +dpo_get_next_node_by_type_and_proto (dpo_type_t child_type, + dpo_proto_t child_proto, + dpo_type_t parent_type, + dpo_proto_t parent_proto); + + +/** + * @brief Barrier sync if a dpo pool is about to expand + * + * @param VM (output) + * vlib_main_t *, invariably &vlib_global_main + * + * @param P + * pool pointer + * + * @param YESNO (output) + * typically a u8, 1 => expand will occur, worker barrier held + * 0 => no expand, barrier not held + * + * @return YESNO set + */ + +#define dpo_pool_barrier_sync(VM,P,YESNO) \ +do { \ + pool_get_aligned_will_expand ((P), YESNO, CLIB_CACHE_LINE_BYTES); \ + \ + if (YESNO) \ + { \ + VM = vlib_get_main(); \ + ASSERT ((VM)->thread_index == 0); \ + vlib_worker_thread_barrier_sync((VM)); \ + } \ +} while(0); + +/** + * @brief Release barrier sync after dpo pool expansion + * + * @param VM + * vlib_main_t pointer, must be &vlib_global_main + * + * @param YESNO + * typically a u8, 1 => release required + * 0 => no release required + * @return none + */ + +#define dpo_pool_barrier_release(VM,YESNO) \ + if ((YESNO)) vlib_worker_thread_barrier_release((VM)); + #endif