X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Fdpo.c;h=d5865d13a1deb8773c6a13cde529afff2ee9cc49;hb=81767d71a943fcf1196867549a6b48122f259695;hp=f4e7fab7bcd567bb0ec8a2c63f1300cdf117a0a5;hpb=53da221b13225695516ec7469ca29d82bb10e594;p=vpp.git diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c index f4e7fab7bcd..d5865d13a1d 100644 --- a/src/vnet/dpo/dpo.c +++ b/src/vnet/dpo/dpo.c @@ -16,9 +16,9 @@ * @brief * A Data-Path Object is an object that represents actions that are * applied to packets are they are switched through VPP. - * + * * The DPO is a base class that is specialised by other objects to provide - * concreate actions + * concrete actions * * The VLIB graph nodes are graph of types, the DPO graph is a graph of instances. */ @@ -43,6 +43,7 @@ #include #include #include +#include /** * Array of char* names for the DPO types and protos @@ -78,7 +79,7 @@ static const char* const * const ** dpo_nodes; * the third dimension in dpo_nodes is lost, hence, the edge index from each * node MUST be the same. * Including both the child and parent protocol is required to support the - * case where it changes as the grapth is traversed, most notablly when an + * case where it changes as the graph is traversed, most notably when an * MPLS label is popped. * * Note that this array is child type specific, not child instance specific. @@ -86,7 +87,7 @@ static const char* const * const ** dpo_nodes; static u32 ****dpo_edges; /** - * @brief The DPO type value that can be assigend to the next dynamic + * @brief The DPO type value that can be assigned to the next dynamic * type registration. */ static dpo_type_t dpo_dynamic = DPO_LAST; @@ -153,20 +154,22 @@ format_dpo_id (u8 * s, va_list * args) if (NULL != dpo_vfts[dpo->dpoi_type].dv_format) { - return (format(s, "%U", - dpo_vfts[dpo->dpoi_type].dv_format, - dpo->dpoi_index, - indent)); + s = format(s, "%U", + dpo_vfts[dpo->dpoi_type].dv_format, + dpo->dpoi_index, + indent); } - - switch (dpo->dpoi_type) + else { - case DPO_FIRST: - s = format(s, "unset"); - break; - default: - s = format(s, "unknown"); - break; + switch (dpo->dpoi_type) + { + case DPO_FIRST: + s = format(s, "unset"); + break; + default: + s = format(s, "unknown"); + break; + } } return (s); } @@ -265,10 +268,10 @@ dpo_copy (dpo_id_t *dst, * the destination is written in a single u64 write - hence atomically w.r.t * any packets inflight. */ - *((u64*)dst) = *(u64*)src; + *((u64*)dst) = *(u64*)src; dpo_lock(dst); - dpo_unlock(&tmp); + dpo_unlock(&tmp); } int @@ -303,6 +306,18 @@ dpo_default_get_next_node (const dpo_id_t *dpo) return (node_indices); } +/** + * A default variant of the make interpose function that just returns + * the original + */ +static void +dpo_default_mk_interpose (const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone) +{ + dpo_copy(clone, original); +} + void dpo_register (dpo_type_t type, const dpo_vft_t *vft, @@ -314,6 +329,10 @@ dpo_register (dpo_type_t type, { dpo_vfts[type].dv_get_next_node = dpo_default_get_next_node; } + if (NULL == dpo_vfts[type].dv_mk_interpose) + { + dpo_vfts[type].dv_mk_interpose = dpo_default_mk_interpose; + } vec_validate(dpo_nodes, type); dpo_nodes[type] = nodes; @@ -330,6 +349,17 @@ dpo_register_new_type (const dpo_vft_t *vft, return (type); } +void +dpo_mk_interpose (const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone) +{ + if (!dpo_id_is_valid(original)) + return; + + dpo_vfts[original->dpoi_type].dv_mk_interpose(original, parent, clone); +} + void dpo_lock (dpo_id_t *dpo) { @@ -379,7 +409,7 @@ dpo_get_next_node (dpo_type_t child_type, parent_proto, ~0); /* - * if the edge index has not yet been created for this node to node transistion + * if the edge index has not yet been created for this node to node transition */ if (~0 == dpo_edges[child_type][child_proto][parent_type][parent_proto]) { @@ -432,6 +462,21 @@ dpo_get_next_node (dpo_type_t child_type, return (dpo_edges[child_type][child_proto][parent_type][parent_proto]); } +/** + * @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. + */ +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) +{ + return (dpo_edges[child_type][child_proto][parent_type][parent_proto]); +} + /** * @brief Stack one DPO object on another, and thus establish a child parent * relationship. The VLIB graph arc used is taken from the parent and child types @@ -450,7 +495,7 @@ dpo_stack_i (u32 edge, dpo_copy(&tmp, parent); /* - * get the edge index for the parent to child VLIB graph transisition + * get the edge index for the parent to child VLIB graph transition */ tmp.dpoi_next_node = edge; @@ -521,6 +566,9 @@ dpo_stack_from_node (u32 child_node_index, } } dpo_stack_i(edge, dpo, parent); + + /* should free this local vector to avoid memory leak */ + vec_free(parent_indices); } static clib_error_t * @@ -541,11 +589,17 @@ dpo_module_init (vlib_main_t * vm) mpls_disp_dpo_module_init(); dvr_dpo_module_init(); l3_proxy_dpo_module_init(); + pw_cw_dpo_module_init(); return (NULL); } -VLIB_INIT_FUNCTION(dpo_module_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION(dpo_module_init) = +{ + .runs_before = VLIB_INITS ("ip_main_init"), +}; +/* *INDENT-ON* */ static clib_error_t * dpo_memory_show (vlib_main_t * vm,