diff options
author | Neale Ranns <nranns@cisco.com> | 2016-08-25 15:29:12 +0100 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2016-09-21 17:37:39 +0000 |
commit | 0bfe5d8c792abcdbcf27bfcc7b7b353fba04aee2 (patch) | |
tree | d600b0e2e693e766e722936744930d3bebac493c /vnet/vnet/mpls-gre/mpls.c | |
parent | 60537f3d83e83d0ce10a620ca99aad4eddf85f5e (diff) |
A Protocol Independent Hierarchical FIB (VPP-352)
Main Enhancements:
- Protocol Independent FIB API
- Hierarchical FIB entries. Dynamic recursive route resolution.
- Extranet Support.
- Integration of IP and MPLS forwarding.
- Separation of FIB and Adjacency databases.
- Data-Plane Object forwarding model.
Change-Id: I52dc815c0d0aa8b493e3cf6b978568f3cc82296c
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'vnet/vnet/mpls-gre/mpls.c')
-rw-r--r-- | vnet/vnet/mpls-gre/mpls.c | 787 |
1 files changed, 0 insertions, 787 deletions
diff --git a/vnet/vnet/mpls-gre/mpls.c b/vnet/vnet/mpls-gre/mpls.c deleted file mode 100644 index d914b4c2b72..00000000000 --- a/vnet/vnet/mpls-gre/mpls.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - * mpls.c: mpls - * - * Copyright (c) 2012 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vnet/vnet.h> -#include <vnet/mpls-gre/mpls.h> - -mpls_main_t mpls_main; - -u8 * format_mpls_gre_tx_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - mpls_gre_tx_trace_t * t = va_arg (*args, mpls_gre_tx_trace_t *); - mpls_main_t * mm = &mpls_main; - - if (t->lookup_miss) - s = format (s, "MPLS: lookup miss"); - else - { - s = format (s, "MPLS: tunnel %d labels %U len %d src %U dst %U", - t->tunnel_id, - format_mpls_encap_index, mm, t->mpls_encap_index, - clib_net_to_host_u16 (t->length), - format_ip4_address, &t->src.as_u8, - format_ip4_address, &t->dst.as_u8); - } - return s; -} - -u8 * format_mpls_eth_tx_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - mpls_eth_tx_trace_t * t = va_arg (*args, mpls_eth_tx_trace_t *); - mpls_main_t * mm = &mpls_main; - - if (t->lookup_miss) - s = format (s, "MPLS: lookup miss"); - else - { - s = format (s, "MPLS: tunnel %d labels %U len %d tx_sw_index %d dst %U", - t->tunnel_id, - format_mpls_encap_index, mm, t->mpls_encap_index, - clib_net_to_host_u16 (t->length), - t->tx_sw_if_index, - format_ethernet_address, t->dst); - } - return s; -} - -u8 * format_mpls_eth_header_with_length (u8 * s, va_list * args) -{ - ethernet_header_t * h = va_arg (*args, ethernet_header_t *); - mpls_unicast_header_t * m = (mpls_unicast_header_t *)(h+1); - u32 max_header_bytes = va_arg (*args, u32); - uword header_bytes; - - header_bytes = sizeof (h[0]); - if (max_header_bytes != 0 && header_bytes > max_header_bytes) - return format (s, "ethernet header truncated"); - - s = format - (s, "ETHERNET-MPLS label %d", - vnet_mpls_uc_get_label (clib_net_to_host_u32 (m->label_exp_s_ttl))); - - return s; -} - -u8 * format_mpls_gre_header_with_length (u8 * s, va_list * args) -{ - gre_header_t * h = va_arg (*args, gre_header_t *); - mpls_unicast_header_t * m = (mpls_unicast_header_t *)(h+1); - u32 max_header_bytes = va_arg (*args, u32); - uword header_bytes; - - header_bytes = sizeof (h[0]); - if (max_header_bytes != 0 && header_bytes > max_header_bytes) - return format (s, "gre header truncated"); - - s = format - (s, "GRE-MPLS label %d", - vnet_mpls_uc_get_label (clib_net_to_host_u32 (m->label_exp_s_ttl))); - - return s; -} - -u8 * format_mpls_gre_header (u8 * s, va_list * args) -{ - gre_header_t * h = va_arg (*args, gre_header_t *); - return format (s, "%U", format_mpls_gre_header_with_length, h, 0); -} - -uword -unformat_mpls_gre_header (unformat_input_t * input, va_list * args) -{ - u8 ** result = va_arg (*args, u8 **); - gre_header_t _g, * g = &_g; - mpls_unicast_header_t _h, * h = &_h; - u32 label, label_exp_s_ttl; - - if (! unformat (input, "MPLS %d", &label)) - return 0; - - g->protocol = clib_host_to_net_u16 (GRE_PROTOCOL_mpls_unicast); - - label_exp_s_ttl = (label<<12) | (1<<8) /* s-bit */ | 0xFF; - h->label_exp_s_ttl = clib_host_to_net_u32 (label_exp_s_ttl); - - /* Add gre, mpls headers to result. */ - { - void * p; - u32 g_n_bytes = sizeof (g[0]); - u32 h_n_bytes = sizeof (h[0]); - - vec_add2 (*result, p, g_n_bytes); - clib_memcpy (p, g, g_n_bytes); - - vec_add2 (*result, p, h_n_bytes); - clib_memcpy (p, h, h_n_bytes); - } - - return 1; -} - -uword -unformat_mpls_label_net_byte_order (unformat_input_t * input, - va_list * args) -{ - u32 * result = va_arg (*args, u32 *); - u32 label; - - if (!unformat (input, "MPLS: label %d", &label)) - return 0; - - label = (label<<12) | (1<<8) /* s-bit set */ | 0xFF /* ttl */; - - *result = clib_host_to_net_u32 (label); - return 1; -} - -mpls_encap_t * -mpls_encap_by_fib_and_dest (mpls_main_t * mm, u32 rx_fib, u32 dst_address) -{ - uword * p; - mpls_encap_t * e; - u64 key; - - key = ((u64)rx_fib<<32) | ((u64) dst_address); - p = hash_get (mm->mpls_encap_by_fib_and_dest, key); - - if (!p) - return 0; - - e = pool_elt_at_index (mm->encaps, p[0]); - return e; -} - -int vnet_mpls_add_del_encap (ip4_address_t *dest, u32 fib_id, - u32 *labels_host_byte_order, - u32 policy_tunnel_index, - int no_dst_hash, u32 * indexp, int is_add) -{ - mpls_main_t * mm = &mpls_main; - ip4_main_t * im = &ip4_main; - mpls_encap_t * e; - u32 label_net_byte_order, label_host_byte_order; - u32 fib_index; - u64 key; - uword *p; - int i; - - p = hash_get (im->fib_index_by_table_id, fib_id); - if (! p) - return VNET_API_ERROR_NO_SUCH_FIB; - - fib_index = p[0]; - - key = ((u64)fib_index<<32) | ((u64) dest->as_u32); - - if (is_add) - { - pool_get (mm->encaps, e); - memset (e, 0, sizeof (*e)); - - for (i = 0; i < vec_len (labels_host_byte_order); i++) - { - mpls_unicast_header_t h; - label_host_byte_order = labels_host_byte_order[i]; - - /* 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 */ - 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; - vec_add1 (e->labels, h); - } - if (no_dst_hash == 0) - hash_set (mm->mpls_encap_by_fib_and_dest, key, e - mm->encaps); - if (indexp) - *indexp = e - mm->encaps; - if (policy_tunnel_index != ~0) - return vnet_mpls_policy_tunnel_add_rewrite (mm, e, policy_tunnel_index); - } - else - { - p = hash_get (mm->mpls_encap_by_fib_and_dest, key); - if (!p) - return VNET_API_ERROR_NO_SUCH_LABEL; - - e = pool_elt_at_index (mm->encaps, p[0]); - - vec_free (e->labels); - vec_free (e->rewrite); - pool_put(mm->encaps, e); - - if (no_dst_hash == 0) - hash_unset (mm->mpls_encap_by_fib_and_dest, key); - } - return 0; -} - -static clib_error_t * -mpls_add_encap_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - u32 fib_id; - u32 *labels = 0; - u32 this_label; - ip4_address_t dest; - u32 policy_tunnel_index = ~0; - int no_dst_hash = 0; - int rv; - int fib_set = 0; - int dest_set = 0; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "fib %d", &fib_id)) - fib_set = 1; - else if (unformat (input, "dest %U", unformat_ip4_address, &dest)) - dest_set = 1; - else if (unformat (input, "no-dst-hash")) - no_dst_hash = 1; - else if (unformat (input, "label %d", &this_label)) - vec_add1 (labels, this_label); - else if (unformat (input, "policy-tunnel %d", &policy_tunnel_index)) - ; - else - break; - } - - if (fib_set == 0) - return clib_error_return (0, "fib-id missing"); - if (dest_set == 0) - return clib_error_return (0, "destination IP address missing"); - if (vec_len (labels) == 0) - return clib_error_return (0, "label stack missing"); - - rv = vnet_mpls_add_del_encap (&dest, fib_id, labels, - policy_tunnel_index, - no_dst_hash, 0 /* indexp */, - 1 /* is_add */); - vec_free (labels); - - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_NO_SUCH_FIB: - return clib_error_return (0, "fib id %d unknown", fib_id); - - default: - return clib_error_return (0, "vnet_mpls_add_del_encap returned %d", - rv); - } - - return 0; -} - -VLIB_CLI_COMMAND (mpls_add_encap_command, static) = { - .path = "mpls encap add", - .short_help = - "mpls encap add label <label> ... fib <id> dest <ip4-address>", - .function = mpls_add_encap_command_fn, -}; - -u8 * format_mpls_unicast_header_host_byte_order (u8 * s, va_list * args) -{ - mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *); - u32 label = h->label_exp_s_ttl; - - s = format (s, "label %d exp %d, s %d, ttl %d", - vnet_mpls_uc_get_label (label), - vnet_mpls_uc_get_exp (label), - vnet_mpls_uc_get_s (label), - vnet_mpls_uc_get_ttl (label)); - return s; -} - -u8 * format_mpls_unicast_header_net_byte_order (u8 * s, va_list * args) -{ - mpls_unicast_header_t *h = va_arg(*args, mpls_unicast_header_t *); - mpls_unicast_header_t h_host; - - h_host.label_exp_s_ttl = clib_net_to_host_u32 (h->label_exp_s_ttl); - - return format (s, "%U", format_mpls_unicast_header_host_byte_order, - &h_host); -} - -static clib_error_t * -mpls_del_encap_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - u32 fib_id; - ip4_address_t dest; - int rv; - - if (unformat (input, "fib %d dest %U", &fib_id, - unformat_ip4_address, &dest)) - { - rv = vnet_mpls_add_del_encap (&dest, fib_id, 0 /* labels */, - ~0 /* policy_tunnel_index */, - 0 /* no_dst_hash */, - 0 /* indexp */, - 0 /* is_add */); - switch (rv) - { - case VNET_API_ERROR_NO_SUCH_FIB: - return clib_error_return (0, "fib id %d unknown", fib_id); - case VNET_API_ERROR_NO_SUCH_ENTRY: - return clib_error_return (0, "dest %U not in fib %d", - format_ip4_address, &dest, fib_id); - default: - break; - } - return 0; - } - else - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); -} - -VLIB_CLI_COMMAND (mpls_del_encap_command, static) = { - .path = "mpls encap delete", - .short_help = "mpls encap delete fib <id> dest <ip4-address>", - .function = mpls_del_encap_command_fn, -}; - -int vnet_mpls_add_del_decap (u32 rx_fib_id, - u32 tx_fib_id, - u32 label_host_byte_order, - int s_bit, int next_index, int is_add) -{ - mpls_main_t * mm = &mpls_main; - ip4_main_t * im = &ip4_main; - mpls_decap_t * d; - u32 rx_fib_index, tx_fib_index_or_output_swif_index; - uword *p; - u64 key; - - p = hash_get (im->fib_index_by_table_id, rx_fib_id); - if (! p) - return VNET_API_ERROR_NO_SUCH_FIB; - - rx_fib_index = p[0]; - - /* L3 decap => transform fib ID to fib index */ - if (next_index == MPLS_INPUT_NEXT_IP4_INPUT) - { - p = hash_get (im->fib_index_by_table_id, tx_fib_id); - if (! p) - return VNET_API_ERROR_NO_SUCH_INNER_FIB; - - tx_fib_index_or_output_swif_index = p[0]; - } - else - { - /* L2 decap, tx_fib_id is actually the output sw_if_index */ - tx_fib_index_or_output_swif_index = tx_fib_id; - } - - key = ((u64) rx_fib_index<<32) | ((u64) label_host_byte_order<<12) - | ((u64) s_bit<<8); - - p = hash_get (mm->mpls_decap_by_rx_fib_and_label, key); - - /* If deleting, or replacing an old entry */ - if (is_add == 0 || p) - { - if (is_add == 0 && p == 0) - return VNET_API_ERROR_NO_SUCH_LABEL; - - d = pool_elt_at_index (mm->decaps, p[0]); - hash_unset (mm->mpls_decap_by_rx_fib_and_label, key); - pool_put (mm->decaps, d); - /* Deleting, we're done... */ - if (is_add == 0) - return 0; - } - - /* add decap entry... */ - pool_get (mm->decaps, d); - memset (d, 0, sizeof (*d)); - d->tx_fib_index = tx_fib_index_or_output_swif_index; - d->next_index = next_index; - - hash_set (mm->mpls_decap_by_rx_fib_and_label, key, d - mm->decaps); - - return 0; -} - -uword -unformat_mpls_gre_input_next (unformat_input_t * input, va_list * args) -{ - u32 * result = va_arg (*args, u32 *); - int rv = 0; - - if (unformat (input, "lookup")) - { - *result = MPLS_INPUT_NEXT_IP4_INPUT; - rv = 1; - } - else if (unformat (input, "output")) - { - *result = MPLS_INPUT_NEXT_L2_OUTPUT; - rv = 1; - } - return rv; -} - -static clib_error_t * -mpls_add_decap_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t * vnm = vnet_get_main(); - u32 rx_fib_id = 0; - u32 tx_fib_or_sw_if_index; - u32 label; - int s_bit = 1; - u32 next_index = 1; /* ip4_lookup, see node.c */ - int tx_fib_id_set = 0; - int label_set = 0; - int rv; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "fib %d", &tx_fib_or_sw_if_index)) - tx_fib_id_set = 1; - else if (unformat (input, "sw_if_index %d", &tx_fib_or_sw_if_index)) - tx_fib_id_set = 1; - else if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, - &tx_fib_or_sw_if_index)) - tx_fib_id_set = 1; - else if (unformat (input, "rx-fib %d", &rx_fib_id)) - ; - else if (unformat (input, "label %d", &label)) - label_set = 1; - else if (unformat (input, "s-bit-clear")) - s_bit = 0; - else if (unformat (input, "next %U", unformat_mpls_gre_input_next, - &next_index)) - ; - else - break; - } - - if (tx_fib_id_set == 0) - return clib_error_return (0, "lookup FIB ID not set"); - if (label_set == 0) - return clib_error_return (0, "missing label"); - - rv = vnet_mpls_add_del_decap (rx_fib_id, tx_fib_or_sw_if_index, - label, s_bit, next_index, 1 /* is_add */); - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_NO_SUCH_FIB: - return clib_error_return (0, "no such rx fib id %d", rx_fib_id); - - case VNET_API_ERROR_NO_SUCH_INNER_FIB: - return clib_error_return (0, "no such tx fib / swif %d", - tx_fib_or_sw_if_index); - - default: - return clib_error_return (0, "vnet_mpls_add_del_decap returned %d", - rv); - } - return 0; -} - -VLIB_CLI_COMMAND (mpls_add_decap_command, static) = { - .path = "mpls decap add", - .short_help = - "mpls decap add fib <id> label <nn> [s-bit-clear] [next-index <nn>]", - .function = mpls_add_decap_command_fn, -}; - -static clib_error_t * -mpls_del_decap_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - u32 rx_fib_id = 0; - u32 tx_fib_id = 0; - u32 label; - int s_bit = 1; - int label_set = 0; - int rv; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "rx-fib %d", &rx_fib_id)) - ; - else if (unformat (input, "label %d", &label)) - label_set = 1; - else if (unformat (input, "s-bit-clear")) - s_bit = 0; - } - - if (!label_set) - return clib_error_return (0, "label not set"); - - rv = vnet_mpls_add_del_decap (rx_fib_id, - tx_fib_id /* not interesting */, - label, s_bit, - 0 /* next_index not interesting */, - 0 /* is_add */); - switch (rv) - { - case 0: - break; - - case VNET_API_ERROR_NO_SUCH_FIB: - return clib_error_return (0, "no such rx fib id %d", rx_fib_id); - - case VNET_API_ERROR_NO_SUCH_INNER_FIB: - return clib_error_return (0, "no such lookup fib id %d", tx_fib_id); - - case VNET_API_ERROR_NO_SUCH_LABEL: - return clib_error_return (0, "no such label %d rx fib id %d", - label, rx_fib_id); - - default: - return clib_error_return (0, "vnet_mpls_add_del_decap returned %d", - rv); - } - return 0; -} - - -VLIB_CLI_COMMAND (mpls_del_decap_command, static) = { - .path = "mpls decap delete", - .short_help = "mpls decap delete label <label> rx-fib <id> [s-bit-clear]", - .function = mpls_del_decap_command_fn, -}; - -int -mpls_dest_cmp(void * a1, void * a2) -{ - show_mpls_fib_t * r1 = a1; - show_mpls_fib_t * r2 = a2; - - return clib_net_to_host_u32(r1->dest) - clib_net_to_host_u32(r2->dest); -} - -int -mpls_fib_index_cmp(void * a1, void * a2) -{ - show_mpls_fib_t * r1 = a1; - show_mpls_fib_t * r2 = a2; - - return r1->fib_index - r2->fib_index; -} - -int -mpls_label_cmp(void * a1, void * a2) -{ - show_mpls_fib_t * r1 = a1; - show_mpls_fib_t * r2 = a2; - - return r1->label - r2->label; -} - -static clib_error_t * -show_mpls_fib_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - u64 key; - u32 value; - 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; - - hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest, - ({ - vec_add2 (records, s, 1); - s->fib_index = (u32)(key>>32); - s->dest = (u32)(key & 0xFFFFFFFF); - s->entry_index = (u32) value; - })); - - 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); - vec_sort_with_function (records, mpls_fib_index_cmp); - vlib_cli_output (vm, "MPLS encap table"); - 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); - 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); - - 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; - } - - vec_sort_with_function (records, mpls_label_cmp); - - 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) - { - 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 = " "; - } - else - { - tx_table_id = d->tx_fib_index; - swif_tag = "(i) "; - } - rx_fib = vec_elt_at_index (im->fibs, s->fib_index); - - 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; -} - -VLIB_CLI_COMMAND (show_mpls_fib_command, static) = { - .path = "show mpls fib", - .short_help = "show mpls fib", - .function = show_mpls_fib_command_fn, -}; - -int mpls_fib_reset_labels (u32 fib_id) -{ - u64 key; - u32 value; - show_mpls_fib_t *records = 0; - show_mpls_fib_t *s; - mpls_main_t * mm = &mpls_main; - ip4_main_t * im = &ip4_main; - u32 fib_index; - uword *p; - - p = hash_get (im->fib_index_by_table_id, fib_id); - if (! p) - return VNET_API_ERROR_NO_SUCH_FIB; - - fib_index = p[0]; - - hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest, - ({ - if (fib_index == (u32)(key>>32)) { - vec_add2 (records, s, 1); - s->dest = (u32)(key & 0xFFFFFFFF); - s->entry_index = (u32) value; - } - })); - - vec_foreach (s, records) - { - key = ((u64)fib_index<<32) | ((u64) s->dest); - hash_unset (mm->mpls_encap_by_fib_and_dest, key); - pool_put_index (mm->encaps, s->entry_index); - } - - vec_reset_length(records); - - hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label, - ({ - if (fib_index == (u32) (key>>32)) { - vec_add2 (records, s, 1); - s->entry_index = value; - s->fib_index = fib_index; - s->s_bit = key & (1<<8); - s->dest = (u32)((key & 0xFFFFFFFF)>>12); - } - })); - - vec_foreach (s, records) - { - key = ((u64) fib_index <<32) | ((u64) s->dest<<12) | - ((u64) s->s_bit); - - hash_unset (mm->mpls_decap_by_rx_fib_and_label, key); - pool_put_index (mm->decaps, s->entry_index); - } - - vec_free(records); - return 0; -} - -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(); - - if ((error = vlib_call_init_function (vm, ip_main_init))) - return error; - - mm->mpls_encap_by_fib_and_dest = hash_create (0, sizeof (uword)); - mm->mpls_decap_by_rx_fib_and_label = hash_create (0, sizeof (uword)); - - return vlib_call_init_function (vm, mpls_input_init); -} - -VLIB_INIT_FUNCTION (mpls_init); - -mpls_main_t * mpls_get_main (vlib_main_t * vm) -{ - vlib_call_init_function (vm, mpls_init); - return &mpls_main; -} - |