2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <plugins/gbp/gbp_sclass.h>
17 #include <vnet/l2/l2_input.h>
18 #include <vnet/l2/l2_output.h>
20 #define foreach_gbp_sclass \
25 #define _(sym,str) GBP_SCLASS_NEXT_##sym,
31 typedef struct gbp_sclass_trace_t_
33 /* per-pkt trace data */
38 static_always_inline uword
39 gbp_sclass_inline (vlib_main_t * vm,
40 vlib_node_runtime_t * node,
41 vlib_frame_t * frame, int is_id_2_sclass, int is_l2)
43 u32 n_left_from, *from, *to_next, next_index;
44 gbp_sclass_main_t *glm;
46 glm = &gbp_sclass_main;
48 n_left_from = frame->n_vectors;
49 from = vlib_frame_vector_args (frame);
51 while (n_left_from > 0)
55 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
57 while (n_left_from > 0 && n_left_to_next > 0)
59 gbp_sclass_next_t next0;
65 next0 = GBP_SCLASS_NEXT_DROP;
73 b0 = vlib_get_buffer (vm, bi0);
77 // output direction - convert from the SRC-EPD to the sclass
78 gbp_endpoint_group_t *gg;
80 epg0 = vnet_buffer2 (b0)->gbp.src_epg;
81 gg = gbp_epg_get (epg0);
85 sclass0 = vnet_buffer2 (b0)->gbp.sclass = gg->gg_sclass;
88 vnet_l2_feature_next (b0, glm->gel_l2_output_feat_next,
89 L2OUTPUT_FEAT_GBP_ID_2_SCLASS);
91 vnet_feature_next (&next0, b0);
98 /* input direction - convert from the sclass to the SRC-EGD */
99 sclass0 = vnet_buffer2 (b0)->gbp.sclass;
100 vnet_buffer2 (b0)->gbp.src_epg =
101 gbp_epg_sclass_2_id (vnet_buffer2 (b0)->gbp.sclass);
102 epg0 = vnet_buffer2 (b0)->gbp.src_epg;
104 if (EPG_INVALID != epg0)
108 vnet_l2_feature_next (b0, glm->gel_l2_input_feat_next,
109 L2INPUT_FEAT_GBP_SCLASS_2_ID);
111 vnet_feature_next (&next0, b0);
115 if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED)))
117 gbp_sclass_trace_t *t =
118 vlib_add_trace (vm, node, b0, sizeof (*t));
123 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
124 to_next, n_left_to_next,
128 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
131 return frame->n_vectors;
134 VLIB_NODE_FN (l2_gbp_id_2_sclass_node) (vlib_main_t * vm,
135 vlib_node_runtime_t * node,
136 vlib_frame_t * frame)
138 return (gbp_sclass_inline (vm, node, frame, 1, 1));
141 VLIB_NODE_FN (l2_gbp_sclass_2_id_node) (vlib_main_t * vm,
142 vlib_node_runtime_t * node,
143 vlib_frame_t * frame)
145 return (gbp_sclass_inline (vm, node, frame, 0, 1));
148 VLIB_NODE_FN (ip4_gbp_id_2_sclass_node) (vlib_main_t * vm,
149 vlib_node_runtime_t * node,
150 vlib_frame_t * frame)
152 return (gbp_sclass_inline (vm, node, frame, 1, 0));
155 VLIB_NODE_FN (ip4_gbp_sclass_2_id_node) (vlib_main_t * vm,
156 vlib_node_runtime_t * node,
157 vlib_frame_t * frame)
159 return (gbp_sclass_inline (vm, node, frame, 0, 0));
162 VLIB_NODE_FN (ip6_gbp_id_2_sclass_node) (vlib_main_t * vm,
163 vlib_node_runtime_t * node,
164 vlib_frame_t * frame)
166 return (gbp_sclass_inline (vm, node, frame, 1, 0));
169 VLIB_NODE_FN (ip6_gbp_sclass_2_id_node) (vlib_main_t * vm,
170 vlib_node_runtime_t * node,
171 vlib_frame_t * frame)
173 return (gbp_sclass_inline (vm, node, frame, 0, 0));
176 /* packet trace format function */
178 format_gbp_sclass_trace (u8 * s, va_list * args)
180 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
181 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
182 gbp_sclass_trace_t *t = va_arg (*args, gbp_sclass_trace_t *);
184 s = format (s, "epg:%d sclass:%d", t->epg, t->sclass);
190 VLIB_REGISTER_NODE (l2_gbp_id_2_sclass_node) = {
191 .name = "l2-gbp-id-2-sclass",
192 .vector_size = sizeof (u32),
193 .format_trace = format_gbp_sclass_trace,
194 .type = VLIB_NODE_TYPE_INTERNAL,
196 .n_next_nodes = GBP_SCLASS_N_NEXT,
199 [GBP_SCLASS_NEXT_DROP] = "error-drop",
202 VLIB_REGISTER_NODE (l2_gbp_sclass_2_id_node) = {
203 .name = "l2-gbp-sclass-2-id",
204 .vector_size = sizeof (u32),
205 .format_trace = format_gbp_sclass_trace,
206 .type = VLIB_NODE_TYPE_INTERNAL,
208 .n_next_nodes = GBP_SCLASS_N_NEXT,
211 [GBP_SCLASS_NEXT_DROP] = "error-drop",
215 VLIB_REGISTER_NODE (ip4_gbp_id_2_sclass_node) = {
216 .name = "ip4-gbp-id-2-sclass",
217 .vector_size = sizeof (u32),
218 .format_trace = format_gbp_sclass_trace,
219 .type = VLIB_NODE_TYPE_INTERNAL,
221 .n_next_nodes = GBP_SCLASS_N_NEXT,
224 [GBP_SCLASS_NEXT_DROP] = "error-drop",
227 VLIB_REGISTER_NODE (ip4_gbp_sclass_2_id_node) = {
228 .name = "ip4-gbp-sclass-2-id",
229 .vector_size = sizeof (u32),
230 .format_trace = format_gbp_sclass_trace,
231 .type = VLIB_NODE_TYPE_INTERNAL,
233 .n_next_nodes = GBP_SCLASS_N_NEXT,
236 [GBP_SCLASS_NEXT_DROP] = "error-drop",
240 VLIB_REGISTER_NODE (ip6_gbp_id_2_sclass_node) = {
241 .name = "ip6-gbp-id-2-sclass",
242 .vector_size = sizeof (u32),
243 .format_trace = format_gbp_sclass_trace,
244 .type = VLIB_NODE_TYPE_INTERNAL,
246 .n_next_nodes = GBP_SCLASS_N_NEXT,
249 [GBP_SCLASS_NEXT_DROP] = "error-drop",
252 VLIB_REGISTER_NODE (ip6_gbp_sclass_2_id_node) = {
253 .name = "ip6-gbp-sclass-2-id",
254 .vector_size = sizeof (u32),
255 .format_trace = format_gbp_sclass_trace,
256 .type = VLIB_NODE_TYPE_INTERNAL,
258 .n_next_nodes = GBP_SCLASS_N_NEXT,
261 [GBP_SCLASS_NEXT_DROP] = "error-drop",
266 VNET_FEATURE_INIT (ip4_gbp_sclass_2_id_feat, static) =
268 .arc_name = "ip4-unicast",
269 .node_name = "ip4-gbp-sclass-2-id",
270 .runs_before = VNET_FEATURES ("gbp-learn-ip4"),
272 VNET_FEATURE_INIT (ip6_gbp_sclass_2_id_feat, static) =
274 .arc_name = "ip6-unicast",
275 .node_name = "ip6-gbp-sclass-2-id",
276 .runs_before = VNET_FEATURES ("gbp-learn-ip6"),
278 VNET_FEATURE_INIT (ip4_gbp_id_2_sclass_feat, static) =
280 .arc_name = "ip4-output",
281 .node_name = "ip4-gbp-id-2-sclass",
283 VNET_FEATURE_INIT (ip6_gbp_id_2_sclass_feat, static) =
285 .arc_name = "ip6-output",
286 .node_name = "ip6-gbp-id-2-sclass",
291 * fd.io coding-style-patch-verification: ON
294 * eval: (c-set-style "gnu")