mpls: Use the .api for the definition of error/info counters
[vpp.git] / src / vnet / mpls / mpls_features.c
1 /*
2  * mpls_features.c: MPLS input and output features
3  *
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:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 #include <vnet/mpls/mpls.h>
19 #include <vnet/mpls/mpls.api_enum.h>
20
21 static u8 *
22 format_mpls_drop_trace (u8 * s, va_list * args)
23 {
24   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
25   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
26
27   s = format (s, "drop");
28   return s;
29 }
30
31 static void
32 mpls_drop_trace (vlib_main_t * vm,
33                  vlib_node_runtime_t * node,
34                  vlib_frame_t * frame)
35 {
36   u32 *from, n_left;
37
38   n_left = frame->n_vectors;
39   from = vlib_frame_vector_args (frame);
40
41   while (n_left >= 1)
42     {
43       vlib_buffer_t *b0;
44       u32 bi0;
45
46       bi0 = from[0];
47
48       b0 = vlib_get_buffer (vm, bi0);
49
50       if (b0->flags & VLIB_BUFFER_IS_TRACED)
51       {
52           vlib_add_trace (vm, node, b0, 0);
53       }
54       from += 1;
55       n_left -= 1;
56     }
57 }
58
59 always_inline uword
60 mpls_terminate (vlib_main_t * vm,
61                 vlib_node_runtime_t * node,
62                 vlib_frame_t * frame,
63                 int error_code)
64 {
65   u32 * buffers = vlib_frame_vector_args (frame);
66   uword n_packets = frame->n_vectors;
67
68   if (node->flags & VLIB_NODE_FLAG_TRACE)
69       mpls_drop_trace (vm, node, frame);
70
71   vlib_error_drop_buffers (vm, node,
72                            buffers,
73                            /* stride */ 1,
74                            n_packets,
75                            /* next */ 0,
76                            mpls_input_node.index,
77                            error_code);
78
79   return n_packets;
80 }
81
82 VLIB_NODE_FN (mpls_punt_node) (vlib_main_t * vm,
83            vlib_node_runtime_t * node,
84            vlib_frame_t * frame)
85 {
86     return (mpls_terminate(vm, node, frame, MPLS_ERROR_PUNT));
87 }
88
89 VLIB_REGISTER_NODE (mpls_punt_node) = {
90   .name = "mpls-punt",
91   .vector_size = sizeof (u32),
92   .format_trace = format_mpls_drop_trace,
93
94   .n_next_nodes = 1,
95   .next_nodes = {
96     [0] = "error-punt",
97   },
98 };
99
100 VLIB_NODE_FN (mpls_drop_node) (vlib_main_t * vm,
101            vlib_node_runtime_t * node,
102            vlib_frame_t * frame)
103 {
104     return (mpls_terminate(vm, node, frame, MPLS_ERROR_DROP));
105 }
106
107 VLIB_REGISTER_NODE (mpls_drop_node) = {
108   .name = "mpls-drop",
109   .vector_size = sizeof (u32),
110   .format_trace = format_mpls_drop_trace,
111
112   .n_next_nodes = 1,
113   .next_nodes = {
114     [0] = "error-drop",
115   },
116 };
117
118 VLIB_NODE_FN (mpls_not_enabled_node) (vlib_main_t * vm,
119                   vlib_node_runtime_t * node,
120                   vlib_frame_t * frame)
121 {
122     return (mpls_terminate(vm, node, frame, MPLS_ERROR_NOT_ENABLED));
123 }
124
125 VLIB_REGISTER_NODE (mpls_not_enabled_node) = {
126   .name = "mpls-not-enabled",
127   .vector_size = sizeof (u32),
128   .format_trace = format_mpls_drop_trace,
129
130   .n_next_nodes = 1,
131   .next_nodes = {
132     [0] = "error-drop",
133   },
134 };
135
136 VNET_FEATURE_ARC_INIT (mpls_input, static) =
137 {
138   .arc_name  = "mpls-input",
139   .start_nodes = VNET_FEATURES ("mpls-input"),
140   .last_in_arc = "mpls-lookup",
141   .arc_index_ptr = &mpls_main.input_feature_arc_index,
142 };
143
144 VNET_FEATURE_INIT (mpls_not_enabled, static) = {
145   .arc_name = "mpls-input",
146   .node_name = "mpls-not-enabled",
147   .runs_before = VNET_FEATURES ("mpls-lookup"),
148 };
149
150 VNET_FEATURE_INIT (mpls_lookup, static) = {
151   .arc_name = "mpls-input",
152   .node_name = "mpls-lookup",
153   .runs_before = VNET_FEATURES (0), /* not before any other features */
154 };
155
156 VNET_FEATURE_ARC_INIT (mpls_output, static) =
157 {
158   .arc_name  = "mpls-output",
159   .start_nodes = VNET_FEATURES ("mpls-output", "mpls-midchain"),
160   .last_in_arc = "interface-output",
161   .arc_index_ptr = &mpls_main.output_feature_arc_index,
162 };
163
164 /* Built-in ip4 tx feature path definition */
165 VNET_FEATURE_INIT (mpls_interface_output, static) = {
166   .arc_name = "mpls-output",
167   .node_name = "interface-output",
168   .runs_before = 0, /* not before any other features */
169 };
170
171 static clib_error_t *
172 mpls_sw_interface_add_del (vnet_main_t * vnm,
173                            u32 sw_if_index,
174                            u32 is_add)
175 {
176   mpls_main_t * mm = &mpls_main;
177
178   vec_validate_init_empty (mm->mpls_enabled_by_sw_if_index, sw_if_index, 0);
179   vec_validate_init_empty (mm->fib_index_by_sw_if_index, sw_if_index, 0);
180
181   vnet_feature_enable_disable ("mpls-input", "mpls-not-enabled", sw_if_index,
182                                is_add, 0, 0);
183
184   return /* no error */ 0;
185 }
186
187 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (mpls_sw_interface_add_del);
188
189