2 * mpls_features.c: MPLS input and output features
4 * Copyright (c) 2016 Cisco and/or its affiliates.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include <vnet/mpls/mpls.h>
21 mpls_terminate (vlib_main_t * vm,
22 vlib_node_runtime_t * node,
26 u32 * buffers = vlib_frame_vector_args (frame);
27 uword n_packets = frame->n_vectors;
29 vlib_error_drop_buffers (vm, node,
34 mpls_input_node.index,
41 mpls_punt (vlib_main_t * vm,
42 vlib_node_runtime_t * node,
45 return (mpls_terminate(vm, node, frame, MPLS_ERROR_PUNT));
48 VLIB_REGISTER_NODE (mpls_punt_node) = {
49 .function = mpls_punt,
51 .vector_size = sizeof (u32),
59 VLIB_NODE_FUNCTION_MULTIARCH (mpls_punt_node, mpls_punt)
62 mpls_drop (vlib_main_t * vm,
63 vlib_node_runtime_t * node,
66 return (mpls_terminate(vm, node, frame, MPLS_ERROR_DROP));
69 VLIB_REGISTER_NODE (mpls_drop_node) = {
70 .function = mpls_drop,
72 .vector_size = sizeof (u32),
80 VLIB_NODE_FUNCTION_MULTIARCH (mpls_drop_node, mpls_drop)
83 mpls_not_enabled (vlib_main_t * vm,
84 vlib_node_runtime_t * node,
87 return (mpls_terminate(vm, node, frame, MPLS_ERROR_NOT_ENABLED));
90 VLIB_REGISTER_NODE (mpls_not_enabled_node) = {
91 .function = mpls_not_enabled,
92 .name = "mpls-not-enabled",
93 .vector_size = sizeof (u32),
101 VLIB_NODE_FUNCTION_MULTIARCH (mpls_not_enabled_node, mpls_not_enabled)
103 VNET_MPLS_FEATURE_INIT (mpls_lookup, static) = {
104 .node_name = "mpls-lookup",
105 .runs_before = ORDER_CONSTRAINTS {"mpls-not-enabled", 0},
106 .feature_index = &mpls_main.mpls_rx_feature_lookup,
109 VNET_MPLS_FEATURE_INIT (mpls_not_enabled, static) = {
110 .node_name = "mpls-not-enabled",
111 .runs_before = ORDER_CONSTRAINTS {0}, /* not before any other features */
112 .feature_index = &mpls_main.mpls_rx_feature_not_enabled,
115 static char * feature_start_nodes[] =
121 mpls_feature_init (vlib_main_t * vm)
123 ip_config_main_t * cm = &mpls_main.rx_config_mains;
124 vnet_config_main_t * vcm = &cm->config_main;
126 return (ip_feature_init_cast (vm, cm, vcm,
128 ARRAY_LEN(feature_start_nodes),
129 VNET_IP_RX_UNICAST_FEAT,
130 VNET_L3_PACKET_TYPE_MPLS_UNICAST));
133 static clib_error_t *
134 mpls_sw_interface_add_del (vnet_main_t * vnm,
138 vlib_main_t * vm = vnm->vlib_main;
139 mpls_main_t * mm = &mpls_main;
140 ip_config_main_t * cm = &mm->rx_config_mains;
141 vnet_config_main_t * vcm = &cm->config_main;
142 u32 drop_feature_index;
145 vec_validate_init_empty (mm->mpls_enabled_by_sw_if_index, sw_if_index, 0);
146 vec_validate_init_empty (mm->fib_index_by_sw_if_index, sw_if_index, 0);
147 vec_validate_init_empty (cm->config_index_by_sw_if_index, sw_if_index, ~0);
148 ci = cm->config_index_by_sw_if_index[sw_if_index];
150 drop_feature_index = mm->mpls_rx_feature_not_enabled;
153 ci = vnet_config_add_feature (vm, vcm, ci,
156 /* # bytes of config data */ 0);
159 ci = vnet_config_del_feature (vm, vcm, ci,
162 /* # bytes of config data */ 0);
163 mm->mpls_enabled_by_sw_if_index[sw_if_index] = 0;;
166 cm->config_index_by_sw_if_index[sw_if_index] = ci;
168 return /* no error */ 0;
171 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (mpls_sw_interface_add_del);
173 static clib_error_t *
174 show_mpls_features_command_fn (vlib_main_t * vm,
175 unformat_input_t * input,
176 vlib_cli_command_t * cmd)
178 mpls_main_t * mm = &mpls_main;
182 vlib_cli_output (vm, "Available MPLS feature nodes");
185 features = mm->feature_nodes;
186 for (i = 0; i < vec_len(features); i++)
187 vlib_cli_output (vm, " %s\n", features[i]);
193 VLIB_CLI_COMMAND (show_ip_features_command, static) = {
194 .path = "show mpls features",
195 .short_help = "show mpls features",
196 .function = show_mpls_features_command_fn,
199 static clib_error_t *
200 show_mpls_interface_features_command_fn (vlib_main_t * vm,
201 unformat_input_t * input,
202 vlib_cli_command_t * cmd)
204 vnet_main_t * vnm = vnet_get_main();
205 mpls_main_t * mm = &mpls_main;
207 ip_config_main_t * cm;
208 vnet_config_main_t * vcm;
211 vnet_config_feature_t * feat;
215 u32 current_config_index;
218 if (! unformat (input, "%U", unformat_vnet_sw_interface,
220 return clib_error_return (0, "Interface not specified...");
222 vlib_cli_output (vm, "MPLS feature paths configured on %U...",
223 format_vnet_sw_if_index_name, vnm, sw_if_index);
225 cm = &mm->rx_config_mains;
226 vcm = &cm->config_main;
228 current_config_index = vec_elt (cm->config_index_by_sw_if_index,
231 ASSERT(current_config_index
232 < vec_len (vcm->config_pool_index_by_user_index));
235 vcm->config_pool_index_by_user_index[current_config_index];
236 cfg = pool_elt_at_index (vcm->config_pool, cfg_index);
238 for (i = 0; i < vec_len(cfg->features); i++)
240 feat = cfg->features + i;
241 node_index = feat->node_index;
242 n = vlib_get_node (vm, node_index);
243 vlib_cli_output (vm, " %v", n->name);
249 VLIB_CLI_COMMAND (show_mpls_interface_features_command, static) = {
250 .path = "show mpls interface features",
251 .short_help = "show mpls interface features <intfc>",
252 .function = show_mpls_interface_features_command_fn,