diff options
Diffstat (limited to 'src/vnet/mpls/interface.c')
-rw-r--r-- | src/vnet/mpls/interface.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/vnet/mpls/interface.c b/src/vnet/mpls/interface.c new file mode 100644 index 00000000000..692a2d1eb62 --- /dev/null +++ b/src/vnet/mpls/interface.c @@ -0,0 +1,121 @@ +/* + * interface.c: mpls interfaces + * + * 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/pg/pg.h> +#include <vnet/mpls/mpls.h> +#include <vnet/fib/ip4_fib.h> +#include <vnet/adj/adj_midchain.h> +#include <vnet/dpo/classify_dpo.h> + + +u8 +mpls_sw_interface_is_enabled (u32 sw_if_index) +{ + mpls_main_t * mm = &mpls_main; + + if (vec_len(mm->mpls_enabled_by_sw_if_index) < sw_if_index) + return (0); + + return (mm->mpls_enabled_by_sw_if_index[sw_if_index]); +} + +void +mpls_sw_interface_enable_disable (mpls_main_t * mm, + u32 sw_if_index, + u8 is_enable) +{ + fib_node_index_t lfib_index; + + vec_validate_init_empty (mm->mpls_enabled_by_sw_if_index, sw_if_index, 0); + + /* + * enable/disable only on the 1<->0 transition + */ + if (is_enable) + { + if (1 != ++mm->mpls_enabled_by_sw_if_index[sw_if_index]) + return; + + lfib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS, + MPLS_FIB_DEFAULT_TABLE_ID); + vec_validate(mm->fib_index_by_sw_if_index, 0); + mm->fib_index_by_sw_if_index[sw_if_index] = lfib_index; + } + else + { + ASSERT(mm->mpls_enabled_by_sw_if_index[sw_if_index] > 0); + if (0 != --mm->mpls_enabled_by_sw_if_index[sw_if_index]) + return; + + fib_table_unlock(mm->fib_index_by_sw_if_index[sw_if_index], + FIB_PROTOCOL_MPLS); + } + + vnet_feature_enable_disable ("mpls-input", "mpls-lookup", sw_if_index, + is_enable, 0, 0); + +} + +static clib_error_t * +mpls_interface_enable_disable (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + vnet_main_t * vnm = vnet_get_main(); + clib_error_t * error = 0; + u32 sw_if_index, enable; + + sw_if_index = ~0; + + if (! unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) + { + error = clib_error_return (0, "unknown interface `%U'", + format_unformat_error, input); + goto done; + } + + if (unformat (input, "enable")) + enable = 1; + else if (unformat (input, "disable")) + enable = 0; + else + { + error = clib_error_return (0, "expected 'enable' or 'disable'", + format_unformat_error, input); + goto done; + } + + mpls_sw_interface_enable_disable(&mpls_main, sw_if_index, enable); + + done: + return error; +} + +/*? + * This command enables an interface to accpet MPLS packets + * + * @cliexpar + * @cliexstart{set interface mpls} + * set interface mpls GigEthernet0/8/0 enable + * @cliexend + ?*/ +VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = { + .path = "set interface mpls", + .function = mpls_interface_enable_disable, + .short_help = "Enable/Disable an interface for MPLS forwarding", +}; |