X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fmpls%2Fmpls.c;fp=vnet%2Fvnet%2Fmpls-gre%2Fmpls.c;h=be5e882f1b3de71b8fe15204c670423716543be2;hb=0bfe5d8c792abcdbcf27bfcc7b7b353fba04aee2;hp=d914b4c2b720bc848b5675ed429902faaf084a66;hpb=60537f3d83e83d0ce10a620ca99aad4eddf85f5e;p=vpp.git diff --git a/vnet/vnet/mpls-gre/mpls.c b/vnet/vnet/mpls/mpls.c similarity index 74% rename from vnet/vnet/mpls-gre/mpls.c rename to vnet/vnet/mpls/mpls.c index d914b4c2b72..be5e882f1b3 100644 --- a/vnet/vnet/mpls-gre/mpls.c +++ b/vnet/vnet/mpls/mpls.c @@ -16,10 +16,86 @@ */ #include -#include +#include +#include +#include + +const static char* mpls_eos_bit_names[] = MPLS_EOS_BITS; mpls_main_t mpls_main; +u8 * format_mpls_unicast_label (u8 * s, va_list * args) +{ + mpls_label_t label = va_arg (*args, mpls_label_t); + + switch (label) { + case MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL: + s = format (s, "%s", MPLS_IETF_IPV4_EXPLICIT_NULL_STRING); + break; + case MPLS_IETF_ROUTER_ALERT_LABEL: + s = format (s, "%s", MPLS_IETF_ROUTER_ALERT_STRING); + break; + case MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL: + s = format (s, "%s", MPLS_IETF_IPV6_EXPLICIT_NULL_STRING); + break; + case MPLS_IETF_IMPLICIT_NULL_LABEL: + s = format (s, "%s", MPLS_IETF_IMPLICIT_NULL_STRING); + break; + case MPLS_IETF_ELI_LABEL: + s = format (s, "%s", MPLS_IETF_ELI_STRING); + break; + case MPLS_IETF_GAL_LABEL: + s = format (s, "%s", MPLS_IETF_GAL_STRING); + break; + default: + s = format (s, "%d", label); + break; + } + return s; +} + +uword unformat_mpls_unicast_label (unformat_input_t * input, va_list * args) +{ + mpls_label_t *label = va_arg (*args, mpls_label_t*); + + if (unformat (input, MPLS_IETF_IPV4_EXPLICIT_NULL_STRING)) + *label = MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL; + else if (unformat (input, MPLS_IETF_IPV6_EXPLICIT_NULL_STRING)) + *label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL; + else if (unformat (input, MPLS_IETF_ROUTER_ALERT_STRING)) + *label = MPLS_IETF_ROUTER_ALERT_LABEL; + else if (unformat (input, MPLS_IETF_IMPLICIT_NULL_STRING)) + *label = MPLS_IETF_IMPLICIT_NULL_LABEL; + else if (unformat (input, "%d", label)) + ; + + return (1); +} + +u8 * format_mpls_eos_bit (u8 * s, va_list * args) +{ + mpls_eos_bit_t eb = va_arg (*args, mpls_eos_bit_t); + + ASSERT(eb <= MPLS_EOS); + + s = format(s, "%s", mpls_eos_bit_names[eb]); + + return (s); +} + +u8 * format_mpls_header (u8 * s, va_list * args) +{ + mpls_unicast_header_t hdr = va_arg (*args, mpls_unicast_header_t); + + return (format(s, "[%U:%d:%d:%U]", + format_mpls_unicast_label, + vnet_mpls_uc_get_label(hdr.label_exp_s_ttl), + vnet_mpls_uc_get_ttl(hdr.label_exp_s_ttl), + vnet_mpls_uc_get_exp(hdr.label_exp_s_ttl), + format_mpls_eos_bit, + vnet_mpls_uc_get_s(hdr.label_exp_s_ttl))); +} + u8 * format_mpls_gre_tx_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); @@ -203,8 +279,9 @@ int vnet_mpls_add_del_encap (ip4_address_t *dest, u32 fib_id, /* Reformat label into mpls_unicast_header_t */ label_host_byte_order <<= 12; - if (i == vec_len(labels_host_byte_order) - 1) - label_host_byte_order |= 1<<8; /* S=1 */ + // FIXME NEOS AND EOS + //if (i == vec_len(labels_host_byte_order) - 1) + // label_host_byte_order |= 1<<8; /* S=1 */ label_host_byte_order |= 0xff; /* TTL=FF */ label_net_byte_order = clib_host_to_net_u32 (label_host_byte_order); h.label_exp_s_ttl = label_net_byte_order; @@ -385,7 +462,7 @@ int vnet_mpls_add_del_decap (u32 rx_fib_id, rx_fib_index = p[0]; /* L3 decap => transform fib ID to fib index */ - if (next_index == MPLS_INPUT_NEXT_IP4_INPUT) + if (next_index == MPLS_LOOKUP_NEXT_IP4_INPUT) { p = hash_get (im->fib_index_by_table_id, tx_fib_id); if (! p) @@ -437,12 +514,12 @@ unformat_mpls_gre_input_next (unformat_input_t * input, va_list * args) if (unformat (input, "lookup")) { - *result = MPLS_INPUT_NEXT_IP4_INPUT; + *result = MPLS_LOOKUP_NEXT_IP4_INPUT; rv = 1; } else if (unformat (input, "output")) { - *result = MPLS_INPUT_NEXT_L2_OUTPUT; + *result = MPLS_LOOKUP_NEXT_L2_OUTPUT; rv = 1; } return rv; @@ -614,10 +691,7 @@ show_mpls_fib_command_fn (vlib_main_t * vm, show_mpls_fib_t *records = 0; show_mpls_fib_t *s; mpls_main_t * mm = &mpls_main; - ip4_main_t * im = &ip4_main; - ip4_fib_t * rx_fib, * tx_fib; - u32 tx_table_id; - char *swif_tag; + ip4_fib_t * rx_fib; hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest, ({ @@ -630,7 +704,6 @@ show_mpls_fib_command_fn (vlib_main_t * vm, if (!vec_len(records)) { vlib_cli_output (vm, "MPLS encap table empty"); - goto decap_table; } /* sort output by dst address within fib */ vec_sort_with_function (records, mpls_dest_cmp); @@ -639,65 +712,174 @@ show_mpls_fib_command_fn (vlib_main_t * vm, vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels"); vec_foreach (s, records) { - rx_fib = vec_elt_at_index (im->fibs, s->fib_index); + rx_fib = ip4_fib_get (s->fib_index); vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id, format_ip4_address, &s->dest, format_mpls_encap_index, mm, s->entry_index); } - decap_table: - vec_reset_length(records); + vec_free(records); + return 0; +} - hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label, - ({ - vec_add2 (records, s, 1); - s->fib_index = (u32)(key>>32); - s->entry_index = (u32) value; - s->label = ((u32) key)>>12; - s->s_bit = (key & (1<<8)) != 0; - })); - - if (!vec_len(records)) - { - vlib_cli_output (vm, "MPLS decap table empty"); - goto out; - } +VLIB_CLI_COMMAND (show_mpls_fib_command, static) = { + .path = "show mpls encap", + .short_help = "show mpls encap", + .function = show_mpls_fib_command_fn, +}; - vec_sort_with_function (records, mpls_label_cmp); +static clib_error_t * +vnet_mpls_local_label (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, * line_input = &_line_input; + fib_route_path_t *rpaths = NULL, rpath; + clib_error_t * error = 0; + u32 table_id, is_del, is_ip; + fib_prefix_t pfx; + mpls_label_t local_label; + mpls_eos_bit_t eos; + + is_ip = 0; + table_id = 0; + eos = MPLS_EOS; + + /* Get a line of input. */ + if (! unformat_user (input, unformat_line_input, line_input)) + return 0; - vlib_cli_output (vm, "MPLS decap table"); - vlib_cli_output (vm, "%=10s%=15s%=6s%=6s", "RX Table", "TX Table/Intfc", - "Label", "S-bit"); - vec_foreach (s, records) + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - mpls_decap_t * d; - d = pool_elt_at_index (mm->decaps, s->entry_index); - if (d->next_index == MPLS_INPUT_NEXT_IP4_INPUT) - { - tx_fib = vec_elt_at_index (im->fibs, d->tx_fib_index); - tx_table_id = tx_fib->table_id; - swif_tag = " "; - } + memset(&rpath, 0, sizeof(rpath)); + memset(&pfx, 0, sizeof(pfx)); + + if (unformat (line_input, "table %d", &table_id)) + ; + else if (unformat (line_input, "del")) + is_del = 1; + else if (unformat (line_input, "add")) + is_del = 0; + else if (unformat (line_input, "eos")) + eos = MPLS_EOS; + else if (unformat (line_input, "non-eos")) + eos = MPLS_NON_EOS; + else if (unformat (line_input, "%U/%d", + unformat_ip4_address, + &pfx.fp_addr.ip4, + &pfx.fp_len)) + { + pfx.fp_proto = FIB_PROTOCOL_IP4; + is_ip = 1; + } + else if (unformat (line_input, "%U/%d", + unformat_ip6_address, + &pfx.fp_addr.ip6, + &pfx.fp_len)) + { + pfx.fp_proto = FIB_PROTOCOL_IP6; + is_ip = 1; + } + else if (unformat (line_input, "%d", &local_label)) + ; + else if (unformat (line_input, + "ip4-lookup-in-table %d", + &rpath.frp_fib_index)) + { + rpath.frp_label = MPLS_LABEL_INVALID; + rpath.frp_proto = FIB_PROTOCOL_IP4; + rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID; + vec_add1(rpaths, rpath); + } + else if (unformat (line_input, + "ip6-lookup-in-table %d", + &rpath.frp_fib_index)) + { + rpath.frp_label = MPLS_LABEL_INVALID; + rpath.frp_proto = FIB_PROTOCOL_IP6; + rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID; + vec_add1(rpaths, rpath); + } + else if (unformat (line_input, + "mpls-lookup-in-table %d", + &rpath.frp_fib_index)) + { + rpath.frp_label = MPLS_LABEL_INVALID; + rpath.frp_proto = FIB_PROTOCOL_IP4; + rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID; + vec_add1(rpaths, rpath); + } else - { - tx_table_id = d->tx_fib_index; - swif_tag = "(i) "; - } - rx_fib = vec_elt_at_index (im->fibs, s->fib_index); + { + error = clib_error_return (0, "unkown input: %U", + format_unformat_error, input); + goto done; + } - vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id, - tx_table_id, swif_tag, s->label, s->s_bit); } - out: - vec_free(records); - return 0; + if (is_ip) + { + u32 fib_index = fib_table_find(pfx.fp_proto, table_id); + + if (FIB_NODE_INDEX_INVALID == fib_index) + { + error = clib_error_return (0, "%U table-id %d does not exist", + format_fib_protocol, pfx.fp_proto, table_id); + goto done; + } + + if (is_del) + { + fib_table_entry_local_label_remove(fib_index, &pfx, local_label); + } + else + { + fib_table_entry_local_label_add(fib_index, &pfx, local_label); + } + } + else + { + fib_node_index_t lfe, fib_index; + fib_prefix_t prefix = { + .fp_proto = FIB_PROTOCOL_MPLS, + .fp_label = local_label, + .fp_eos = eos, + }; + + fib_index = mpls_fib_index_from_table_id(table_id); + + if (FIB_NODE_INDEX_INVALID == fib_index) + { + error = clib_error_return (0, "MPLS table-id %d does not exist", + table_id); + goto done; + } + + lfe = fib_table_entry_path_add2(fib_index, + &prefix, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_NONE, + rpaths); + + if (FIB_NODE_INDEX_INVALID == lfe) + { + error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d", + format_mpls_unicast_label, local_label, + format_mpls_eos_bit, eos, + table_id); + goto done; + } + } + +done: + return error; } -VLIB_CLI_COMMAND (show_mpls_fib_command, static) = { - .path = "show mpls fib", - .short_help = "show mpls fib", - .function = show_mpls_fib_command_fn, +VLIB_CLI_COMMAND (mpls_local_label_command, static) = { + .path = "mpls local-label", + .function = vnet_mpls_local_label, + .short_help = "Create/Delete MPL local labels", }; int mpls_fib_reset_labels (u32 fib_id) @@ -764,7 +946,6 @@ static clib_error_t * mpls_init (vlib_main_t * vm) mpls_main_t * mm = &mpls_main; clib_error_t * error; - memset (mm, 0, sizeof (mm[0])); mm->vlib_main = vm; mm->vnet_main = vnet_get_main();