X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_path_ext.c;h=209b6273a85c6247aa58f1fccac85a42b4dad507;hb=775f73c6b;hp=45ab1f1498d33119431021e719cd5870216e0827;hpb=8142499cd1cb3b8d0168d0e6cf5309c5b4813cc4;p=vpp.git diff --git a/src/vnet/fib/fib_path_ext.c b/src/vnet/fib/fib_path_ext.c index 45ab1f1498d..209b6273a85 100644 --- a/src/vnet/fib/fib_path_ext.c +++ b/src/vnet/fib/fib_path_ext.c @@ -25,6 +25,7 @@ #include const char *fib_path_ext_adj_flags_names[] = FIB_PATH_EXT_ADJ_ATTR_NAMES; +const char *fib_path_ext_mpls_flags_names[] = FIB_PATH_EXT_MPLS_ATTR_NAMES; u8 * format_fib_path_ext (u8 * s, va_list * args) @@ -38,30 +39,45 @@ format_fib_path_ext (u8 * s, va_list * args) switch (path_ext->fpe_type) { - case FIB_PATH_EXT_MPLS: - s = format(s, "labels:", - path_ext->fpe_path_index); + case FIB_PATH_EXT_MPLS: { + fib_path_ext_mpls_attr_t attr; + + if (path_ext->fpe_mpls_flags) + { + s = format(s, "mpls-flags:["); + + FOR_EACH_PATH_EXT_MPLS_ATTR(attr) + { + if ((1<fpe_mpls_flags) { + s = format(s, "%s", fib_path_ext_mpls_flags_names[attr]); + } + } + s = format(s, "]"); + } + s = format(s, " labels:["); for (ii = 0; ii < vec_len(path_ext->fpe_path.frp_label_stack); ii++) { - s = format(s, "%U ", - format_mpls_unicast_label, - path_ext->fpe_path.frp_label_stack[ii]); + s = format(s, "[%U]", + format_fib_mpls_label, + &path_ext->fpe_path.frp_label_stack[ii]); } + s = format(s, "]"); break; + } case FIB_PATH_EXT_ADJ: { fib_path_ext_adj_attr_t attr; - s = format(s, "adj-flags:"); if (path_ext->fpe_adj_flags) { + s = format(s, "adj-flags:["); FOR_EACH_PATH_EXT_ADJ_ATTR(attr) { - s = format(s, "%s", fib_path_ext_adj_flags_names[attr]); + if ((1<fpe_adj_flags) + { + s = format(s, "%s", fib_path_ext_adj_flags_names[attr]); + } } - } - else - { - s = format(s, "None"); + s = format(s, "]"); } break; } @@ -105,7 +121,7 @@ fib_path_ext_resolve (fib_path_ext_t *path_ext, path_ext); } -void +static void fib_path_ext_init (fib_path_ext_t *path_ext, fib_node_index_t path_list_index, fib_path_ext_type_t ext_type, @@ -121,12 +137,28 @@ fib_path_ext_init (fib_path_ext_t *path_ext, /** * @brief Return true if the label stack is implicit null + * imp-null and pop equate to the same this as this level - + * the label is coming off. */ static int fib_path_ext_is_imp_null (fib_path_ext_t *path_ext) { return ((1 == vec_len(path_ext->fpe_label_stack)) && - (MPLS_IETF_IMPLICIT_NULL_LABEL == path_ext->fpe_label_stack[0])); + ((MPLS_IETF_IMPLICIT_NULL_LABEL == path_ext->fpe_label_stack[0].fml_value) || + (MPLS_LABEL_POP == path_ext->fpe_label_stack[0].fml_value))); +} + +mpls_label_dpo_flags_t +fib_path_ext_mpls_flags_to_mpls_label (fib_path_ext_mpls_flags_t fpe_flags) +{ + mpls_label_dpo_flags_t ml_flags = MPLS_LABEL_DPO_FLAG_NONE; + + if (fpe_flags &FIB_PATH_EXT_MPLS_FLAG_NO_IP_TTL_DECR) + { + ml_flags |= MPLS_LABEL_DPO_FLAG_NO_IP_TTL_DECR; + } + + return (ml_flags); } load_balance_path_t * @@ -191,6 +223,9 @@ fib_path_ext_stack (fib_path_ext_t *path_ext, case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: parent_fct = child_fct; break; + case FIB_FORW_CHAIN_TYPE_ETHERNET: + parent_fct = FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS; + break; default: return (nhs); break; @@ -233,25 +268,36 @@ fib_path_ext_stack (fib_path_ext_t *path_ext, * we pickup the correct MPLS imposition nodes to do * ip[46] processing. */ + dpo_id_t parent = DPO_INVALID; dpo_proto_t chain_proto; mpls_eos_bit_t eos; - index_t mldi; eos = (child_fct == FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS ? MPLS_NON_EOS : MPLS_EOS); chain_proto = fib_forw_chain_type_to_dpo_proto(child_fct); - mldi = mpls_label_dpo_create(path_ext->fpe_label_stack, - eos, 255, 0, - chain_proto, - &nh->path_dpo); + dpo_copy(&parent, &nh->path_dpo); + mpls_label_dpo_create(path_ext->fpe_label_stack, + eos, + chain_proto, + fib_path_ext_mpls_flags_to_mpls_label( + path_ext->fpe_mpls_flags), + &parent, + &nh->path_dpo); - dpo_set(&nh->path_dpo, - DPO_MPLS_LABEL, - chain_proto, - mldi); + dpo_reset(&parent); } + else if (child_fct == FIB_FORW_CHAIN_TYPE_MPLS_EOS) + { + /* + * MPLS EOS packets using an imp-null. Insert the disposition. + */ + fib_path_stack_mpls_disp(nh->path_index, + fib_forw_chain_type_to_dpo_proto(parent_fct), + path_ext->fpe_label_stack[0].fml_mode, + &nh->path_dpo); + } } dpo_reset(&via_dpo); @@ -282,11 +328,14 @@ fib_path_ext_list_find_by_path_index (const fib_path_ext_list_t *list, { fib_path_ext_t *path_ext; - vec_foreach(path_ext, list->fpel_exts) + if (NULL != list) { - if (path_ext->fpe_path_index == path_index) + vec_foreach(path_ext, list->fpel_exts) { - return (path_ext); + if (path_ext->fpe_path_index == path_index) + { + return (path_ext); + } } } return (NULL); @@ -338,7 +387,18 @@ fib_path_ext_list_insert (fib_path_ext_list_t *list, vec_foreach(path_ext, list->fpel_exts) { - if (fib_path_ext_cmp(path_ext, rpath) < 0) + int res = fib_path_ext_cmp(path_ext, rpath); + + if (0 == res) + { + /* + * don't add duplicate extensions. modify instead + */ + vec_free(path_ext->fpe_label_stack); + *path_ext = new_path_ext; + goto done; + } + else if (res < 0) { i++; } @@ -348,7 +408,7 @@ fib_path_ext_list_insert (fib_path_ext_list_t *list, } } vec_insert_elts(list->fpel_exts, &new_path_ext, 1, i); - +done: return (&(list->fpel_exts[i])); }