Line data Source code
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 54 : format_mpls_drop_trace (u8 * s, va_list * args)
23 : {
24 54 : CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
25 54 : CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
26 :
27 54 : s = format (s, "drop");
28 54 : return s;
29 : }
30 :
31 : static void
32 5 : 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 5 : n_left = frame->n_vectors;
39 5 : from = vlib_frame_vector_args (frame);
40 :
41 265 : while (n_left >= 1)
42 : {
43 : vlib_buffer_t *b0;
44 : u32 bi0;
45 :
46 260 : bi0 = from[0];
47 :
48 260 : b0 = vlib_get_buffer (vm, bi0);
49 :
50 260 : if (b0->flags & VLIB_BUFFER_IS_TRACED)
51 : {
52 260 : vlib_add_trace (vm, node, b0, 0);
53 : }
54 260 : from += 1;
55 260 : n_left -= 1;
56 : }
57 5 : }
58 :
59 : always_inline uword
60 5 : mpls_terminate (vlib_main_t * vm,
61 : vlib_node_runtime_t * node,
62 : vlib_frame_t * frame,
63 : int error_code)
64 : {
65 5 : u32 * buffers = vlib_frame_vector_args (frame);
66 5 : uword n_packets = frame->n_vectors;
67 :
68 5 : if (node->flags & VLIB_NODE_FLAG_TRACE)
69 5 : mpls_drop_trace (vm, node, frame);
70 :
71 5 : 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 5 : return n_packets;
80 : }
81 :
82 2300 : VLIB_NODE_FN (mpls_punt_node) (vlib_main_t * vm,
83 : vlib_node_runtime_t * node,
84 : vlib_frame_t * frame)
85 : {
86 0 : return (mpls_terminate(vm, node, frame, MPLS_ERROR_PUNT));
87 : }
88 :
89 183788 : 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 2302 : VLIB_NODE_FN (mpls_drop_node) (vlib_main_t * vm,
101 : vlib_node_runtime_t * node,
102 : vlib_frame_t * frame)
103 : {
104 2 : return (mpls_terminate(vm, node, frame, MPLS_ERROR_DROP));
105 : }
106 :
107 183788 : 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 2303 : VLIB_NODE_FN (mpls_not_enabled_node) (vlib_main_t * vm,
119 : vlib_node_runtime_t * node,
120 : vlib_frame_t * frame)
121 : {
122 3 : return (mpls_terminate(vm, node, frame, MPLS_ERROR_NOT_ENABLED));
123 : }
124 :
125 183788 : 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 1151 : 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 76635 : 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 76635 : 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 1151 : 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 76635 : 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 11798 : mpls_sw_interface_add_del (vnet_main_t * vnm,
173 : u32 sw_if_index,
174 : u32 is_add)
175 : {
176 11798 : mpls_main_t * mm = &mpls_main;
177 :
178 15752 : vec_validate_init_empty (mm->mpls_enabled_by_sw_if_index, sw_if_index, 0);
179 15752 : vec_validate_init_empty (mm->fib_index_by_sw_if_index, sw_if_index, 0);
180 :
181 11798 : vnet_feature_enable_disable ("mpls-input", "mpls-not-enabled", sw_if_index,
182 : is_add, 0, 0);
183 :
184 11798 : return /* no error */ 0;
185 : }
186 :
187 3459 : VNET_SW_INTERFACE_ADD_DEL_FUNCTION (mpls_sw_interface_add_del);
188 :
189 :
|