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.h>
17 #include <vnet/l2/l2_input.h>
18 #include <vnet/l2/l2_output.h>
21 * Grouping of global data for the GBP source EPG classification feature
23 typedef struct gbp_sclass_main_t_
26 * Next nodes for L2 output features
28 u32 gel_l2_input_feat_next[32];
29 u32 gel_l2_output_feat_next[32];
32 static gbp_sclass_main_t gbp_sclass_main;
34 #define foreach_gbp_sclass \
40 #define _(sym,str) GBP_SCLASS_NEXT_##sym,
46 typedef struct gbp_sclass_trace_t_
48 /* per-pkt trace data */
54 gbp_sclass_inline (vlib_main_t * vm,
55 vlib_node_runtime_t * node,
56 vlib_frame_t * frame, int is_id_2_sclass, int is_l2)
58 u32 n_left_from, *from, *to_next, next_index;
59 gbp_sclass_main_t *glm;
61 glm = &gbp_sclass_main;
63 n_left_from = frame->n_vectors;
64 from = vlib_frame_vector_args (frame);
66 while (n_left_from > 0)
70 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
72 while (n_left_from > 0 && n_left_to_next > 0)
74 gbp_sclass_next_t next0;
80 next0 = GBP_SCLASS_NEXT_DROP;
88 b0 = vlib_get_buffer (vm, bi0);
92 // output direction - convert from the SRC-EPD to the sclass
93 gbp_endpoint_group_t *gg;
95 epg0 = vnet_buffer2 (b0)->gbp.src_epg;
96 gg = gbp_epg_get (epg0);
100 sclass0 = vnet_buffer2 (b0)->gbp.sclass = gg->gg_sclass;
103 vnet_l2_feature_next (b0, glm->gel_l2_output_feat_next,
104 L2OUTPUT_FEAT_GBP_ID_2_SCLASS);
106 vnet_feature_next (&next0, b0);
113 /* input direction - convert from the sclass to the SRC-EGD */
114 sclass0 = vnet_buffer2 (b0)->gbp.sclass;
115 vnet_buffer2 (b0)->gbp.src_epg =
116 gbp_epg_sclass_2_id (vnet_buffer2 (b0)->gbp.sclass);
117 epg0 = vnet_buffer2 (b0)->gbp.src_epg;
119 if (EPG_INVALID != epg0)
123 vnet_l2_feature_next (b0, glm->gel_l2_input_feat_next,
124 L2INPUT_FEAT_GBP_SCLASS_2_ID);
126 vnet_feature_next (&next0, b0);
130 if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED)))
132 gbp_sclass_trace_t *t =
133 vlib_add_trace (vm, node, b0, sizeof (*t));
138 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
139 to_next, n_left_to_next,
143 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
146 return frame->n_vectors;
150 l2_gbp_id_2_sclass (vlib_main_t * vm,
151 vlib_node_runtime_t * node, vlib_frame_t * frame)
153 return (gbp_sclass_inline (vm, node, frame, 1, 1));
157 l2_gbp_sclass_2_id (vlib_main_t * vm,
158 vlib_node_runtime_t * node, vlib_frame_t * frame)
160 return (gbp_sclass_inline (vm, node, frame, 0, 1));
164 ip4_gbp_id_2_sclass (vlib_main_t * vm,
165 vlib_node_runtime_t * node, vlib_frame_t * frame)
167 return (gbp_sclass_inline (vm, node, frame, 1, 0));
171 ip4_gbp_sclass_2_id (vlib_main_t * vm,
172 vlib_node_runtime_t * node, vlib_frame_t * frame)
174 return (gbp_sclass_inline (vm, node, frame, 0, 0));
178 ip6_gbp_id_2_sclass (vlib_main_t * vm,
179 vlib_node_runtime_t * node, vlib_frame_t * frame)
181 return (gbp_sclass_inline (vm, node, frame, 1, 0));
185 ip6_gbp_sclass_2_id (vlib_main_t * vm,
186 vlib_node_runtime_t * node, vlib_frame_t * frame)
188 return (gbp_sclass_inline (vm, node, frame, 0, 0));
191 /* packet trace format function */
193 format_gbp_sclass_trace (u8 * s, va_list * args)
195 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
196 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
197 gbp_sclass_trace_t *t = va_arg (*args, gbp_sclass_trace_t *);
199 s = format (s, "epg:%d sclass:%d", t->epg, t->sclass);
205 VLIB_REGISTER_NODE (l2_gbp_id_2_sclass_node) = {
206 .function = l2_gbp_id_2_sclass,
207 .name = "l2-gbp-id-2-sclass",
208 .vector_size = sizeof (u32),
209 .format_trace = format_gbp_sclass_trace,
210 .type = VLIB_NODE_TYPE_INTERNAL,
212 .n_next_nodes = GBP_SCLASS_N_NEXT,
215 [GBP_SCLASS_NEXT_DROP] = "error-drop",
218 VLIB_REGISTER_NODE (l2_gbp_sclass_2_id_node) = {
219 .function = l2_gbp_sclass_2_id,
220 .name = "l2-gbp-sclass-2-id",
221 .vector_size = sizeof (u32),
222 .format_trace = format_gbp_sclass_trace,
223 .type = VLIB_NODE_TYPE_INTERNAL,
225 .n_next_nodes = GBP_SCLASS_N_NEXT,
228 [GBP_SCLASS_NEXT_DROP] = "error-drop",
232 VLIB_REGISTER_NODE (ip4_gbp_id_2_sclass_node) = {
233 .function = ip4_gbp_id_2_sclass,
234 .name = "ip4-gbp-id-2-sclass",
235 .vector_size = sizeof (u32),
236 .format_trace = format_gbp_sclass_trace,
237 .type = VLIB_NODE_TYPE_INTERNAL,
239 .n_next_nodes = GBP_SCLASS_N_NEXT,
242 [GBP_SCLASS_NEXT_DROP] = "error-drop",
245 VLIB_REGISTER_NODE (ip4_gbp_sclass_2_id_node) = {
246 .function = ip4_gbp_sclass_2_id,
247 .name = "ip4-gbp-sclass-2-id",
248 .vector_size = sizeof (u32),
249 .format_trace = format_gbp_sclass_trace,
250 .type = VLIB_NODE_TYPE_INTERNAL,
252 .n_next_nodes = GBP_SCLASS_N_NEXT,
255 [GBP_SCLASS_NEXT_DROP] = "error-drop",
259 VLIB_REGISTER_NODE (ip6_gbp_id_2_sclass_node) = {
260 .function = ip6_gbp_id_2_sclass,
261 .name = "ip6-gbp-id-2-sclass",
262 .vector_size = sizeof (u32),
263 .format_trace = format_gbp_sclass_trace,
264 .type = VLIB_NODE_TYPE_INTERNAL,
266 .n_next_nodes = GBP_SCLASS_N_NEXT,
269 [GBP_SCLASS_NEXT_DROP] = "error-drop",
272 VLIB_REGISTER_NODE (ip6_gbp_sclass_2_id_node) = {
273 .function = ip6_gbp_sclass_2_id,
274 .name = "ip6-gbp-sclass-2-id",
275 .vector_size = sizeof (u32),
276 .format_trace = format_gbp_sclass_trace,
277 .type = VLIB_NODE_TYPE_INTERNAL,
279 .n_next_nodes = GBP_SCLASS_N_NEXT,
282 [GBP_SCLASS_NEXT_DROP] = "error-drop",
286 VLIB_NODE_FUNCTION_MULTIARCH (l2_gbp_id_2_sclass_node, l2_gbp_id_2_sclass);
287 VLIB_NODE_FUNCTION_MULTIARCH (l2_gbp_sclass_2_id_node, l2_gbp_sclass_2_id);
289 VLIB_NODE_FUNCTION_MULTIARCH (ip4_gbp_id_2_sclass_node, ip4_gbp_id_2_sclass);
290 VLIB_NODE_FUNCTION_MULTIARCH (ip4_gbp_sclass_2_id_node, ip4_gbp_sclass_2_id);
291 VLIB_NODE_FUNCTION_MULTIARCH (ip6_gbp_id_2_sclass_node, ip6_gbp_id_2_sclass);
292 VLIB_NODE_FUNCTION_MULTIARCH (ip6_gbp_sclass_2_id_node, ip6_gbp_sclass_2_id);
294 VNET_FEATURE_INIT (ip4_gbp_sclass_2_id_feat, static) =
296 .arc_name = "ip4-unicast",
297 .node_name = "ip4-gbp-sclass-2-id",
298 .runs_before = VNET_FEATURES ("gbp-learn-ip4"),
300 VNET_FEATURE_INIT (ip6_gbp_sclass_2_id_feat, static) =
302 .arc_name = "ip6-unicast",
303 .node_name = "ip6-gbp-sclass-2-id",
304 .runs_before = VNET_FEATURES ("gbp-learn-ip6"),
306 VNET_FEATURE_INIT (ip4_gbp_id_2_sclass_feat, static) =
308 .arc_name = "ip4-output",
309 .node_name = "ip4-gbp-id-2-sclass",
311 VNET_FEATURE_INIT (ip6_gbp_id_2_sclass_feat, static) =
313 .arc_name = "ip6-output",
314 .node_name = "ip6-gbp-id-2-sclass",
319 gbp_sclass_enable_l2 (u32 sw_if_index)
321 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SCLASS_2_ID, 1);
322 l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_ID_2_SCLASS, 1);
326 gbp_sclass_disable_l2 (u32 sw_if_index)
328 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SCLASS_2_ID, 0);
329 l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_ID_2_SCLASS, 0);
333 gbp_sclass_enable_ip (u32 sw_if_index)
335 vnet_feature_enable_disable ("ip4-unicast",
336 "ip4-gbp-sclass-2-id", sw_if_index, 1, 0, 0);
337 vnet_feature_enable_disable ("ip6-unicast",
338 "ip6-gbp-sclass-2-id", sw_if_index, 1, 0, 0);
339 vnet_feature_enable_disable ("ip4-output",
340 "ip4-gbp-id-2-sclass", sw_if_index, 1, 0, 0);
341 vnet_feature_enable_disable ("ip6-output",
342 "ip6-gbp-id-2-sclass", sw_if_index, 1, 0, 0);
346 gbp_sclass_disable_ip (u32 sw_if_index)
348 vnet_feature_enable_disable ("ip4-unicast",
349 "ip4-gbp-sclass-2-id", sw_if_index, 0, 0, 0);
350 vnet_feature_enable_disable ("ip6-unicast",
351 "ip6-gbp-sclass-2-id", sw_if_index, 0, 0, 0);
352 vnet_feature_enable_disable ("ip4-output",
353 "ip4-gbp-id-2-sclass", sw_if_index, 0, 0, 0);
354 vnet_feature_enable_disable ("ip6-output",
355 "ip6-gbp-id-2-sclass", sw_if_index, 0, 0, 0);
358 static clib_error_t *
359 gbp_sclass_init (vlib_main_t * vm)
361 gbp_sclass_main_t *glm = &gbp_sclass_main;
363 /* Initialize the feature next-node indices */
364 feat_bitmap_init_next_nodes (vm,
365 l2_gbp_sclass_2_id_node.index,
367 l2input_get_feat_names (),
368 glm->gel_l2_input_feat_next);
369 feat_bitmap_init_next_nodes (vm,
370 l2_gbp_id_2_sclass_node.index,
372 l2output_get_feat_names (),
373 glm->gel_l2_output_feat_next);
378 VLIB_INIT_FUNCTION (gbp_sclass_init);
381 * fd.io coding-style-patch-verification: ON
384 * eval: (c-set-style "gnu")