2 * gbp.h : Group Based Policy
4 * Copyright (c) 2018 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 <plugins/gbp/gbp.h>
19 #include <vnet/l2/l2_input.h>
20 #include <vnet/l2/feat_bitmap.h>
22 typedef enum gbp_src_classify_type_t_
24 GBP_SRC_CLASSIFY_NULL,
25 GBP_SRC_CLASSIFY_PORT,
26 } gbp_src_classify_type_t;
28 #define GBP_SRC_N_CLASSIFY (GBP_SRC_CLASSIFY_PORT + 1)
31 * Grouping of global data for the GBP source EPG classification feature
33 typedef struct gbp_src_classify_main_t_
36 * Next nodes for L2 output features
38 u32 l2_input_feat_next[GBP_SRC_N_CLASSIFY][32];
39 } gbp_src_classify_main_t;
41 static gbp_src_classify_main_t gbp_src_classify_main;
44 * per-packet trace data
46 typedef struct gbp_classify_trace_t_
48 /* per-pkt trace data */
50 } gbp_classify_trace_t;
53 * determine the SRC EPG form the input port
56 gbp_classify_inline (vlib_main_t * vm,
57 vlib_node_runtime_t * node,
59 gbp_src_classify_type_t type, u8 is_l3)
61 gbp_src_classify_main_t *gscm = &gbp_src_classify_main;
62 u32 n_left_from, *from, *to_next;
66 n_left_from = frame->n_vectors;
67 from = vlib_frame_vector_args (frame);
69 while (n_left_from > 0)
73 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
75 while (n_left_from > 0 && n_left_to_next > 0)
77 u32 next0, bi0, src_epg, sw_if_index0;
78 const gbp_endpoint_t *gep0;
88 b0 = vlib_get_buffer (vm, bi0);
90 sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
92 if (GBP_SRC_CLASSIFY_NULL == type)
94 src_epg = EPG_INVALID;
96 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
97 L2INPUT_FEAT_GBP_NULL_CLASSIFY);
101 gep0 = gbp_endpoint_get_itf (sw_if_index0);
102 src_epg = gep0->ge_epg_id;
106 * Go straight to lookup, do not pass go, do not collect $200
113 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
114 L2INPUT_FEAT_GBP_SRC_CLASSIFY);
118 vnet_buffer2 (b0)->gbp.src_epg = src_epg;
120 if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED)))
122 gbp_classify_trace_t *t =
123 vlib_add_trace (vm, node, b0, sizeof (*t));
124 t->src_epg = src_epg;
127 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
128 to_next, n_left_to_next,
132 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
135 return frame->n_vectors;
139 gbp_src_classify (vlib_main_t * vm,
140 vlib_node_runtime_t * node, vlib_frame_t * frame)
142 return (gbp_classify_inline (vm, node, frame, GBP_SRC_CLASSIFY_PORT, 0));
146 gbp_null_classify (vlib_main_t * vm,
147 vlib_node_runtime_t * node, vlib_frame_t * frame)
149 return (gbp_classify_inline (vm, node, frame, GBP_SRC_CLASSIFY_NULL, 0));
153 gbp_ip4_src_classify (vlib_main_t * vm,
154 vlib_node_runtime_t * node, vlib_frame_t * frame)
156 return (gbp_classify_inline (vm, node, frame, 0, 1));
160 gbp_ip6_src_classify (vlib_main_t * vm,
161 vlib_node_runtime_t * node, vlib_frame_t * frame)
163 return (gbp_classify_inline (vm, node, frame, 0, 1));
167 /* packet trace format function */
169 format_gbp_classify_trace (u8 * s, va_list * args)
171 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
172 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
173 gbp_classify_trace_t *t = va_arg (*args, gbp_classify_trace_t *);
175 s = format (s, "src-epg:%d", t->src_epg);
181 VLIB_REGISTER_NODE (gbp_null_classify_node) = {
182 .function = gbp_null_classify,
183 .name = "gbp-null-classify",
184 .vector_size = sizeof (u32),
185 .format_trace = format_gbp_classify_trace,
186 .type = VLIB_NODE_TYPE_INTERNAL,
192 VLIB_NODE_FUNCTION_MULTIARCH (gbp_null_classify_node, gbp_null_classify);
194 VLIB_REGISTER_NODE (gbp_src_classify_node) = {
195 .function = gbp_src_classify,
196 .name = "gbp-src-classify",
197 .vector_size = sizeof (u32),
198 .format_trace = format_gbp_classify_trace,
199 .type = VLIB_NODE_TYPE_INTERNAL,
205 VLIB_NODE_FUNCTION_MULTIARCH (gbp_src_classify_node, gbp_src_classify);
207 VLIB_REGISTER_NODE (gbp_ip4_src_classify_node) = {
208 .function = gbp_ip4_src_classify,
209 .name = "ip4-gbp-src-classify",
210 .vector_size = sizeof (u32),
211 .format_trace = format_gbp_classify_trace,
212 .type = VLIB_NODE_TYPE_INTERNAL,
221 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip4_src_classify_node, gbp_ip4_src_classify);
223 VLIB_REGISTER_NODE (gbp_ip6_src_classify_node) = {
224 .function = gbp_ip6_src_classify,
225 .name = "ip6-gbp-src-classify",
226 .vector_size = sizeof (u32),
227 .format_trace = format_gbp_classify_trace,
228 .type = VLIB_NODE_TYPE_INTERNAL,
237 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip6_src_classify_node, gbp_ip6_src_classify);
239 VNET_FEATURE_INIT (gbp_ip4_src_classify_feat_node, static) =
241 .arc_name = "ip4-unicast",
242 .node_name = "ip4-gbp-src-classify",
243 .runs_before = VNET_FEATURES ("nat44-out2in"),
245 VNET_FEATURE_INIT (gbp_ip6_src_classify_feat_node, static) =
247 .arc_name = "ip6-unicast",
248 .node_name = "ip6-gbp-src-classify",
249 .runs_before = VNET_FEATURES ("nat66-out2in"),
252 static clib_error_t *
253 gbp_src_classify_init (vlib_main_t * vm)
255 gbp_src_classify_main_t *em = &gbp_src_classify_main;
257 /* Initialize the feature next-node indexes */
258 feat_bitmap_init_next_nodes (vm,
259 gbp_src_classify_node.index,
261 l2input_get_feat_names (),
262 em->l2_input_feat_next[GBP_SRC_CLASSIFY_NULL]);
263 feat_bitmap_init_next_nodes (vm,
264 gbp_null_classify_node.index,
266 l2input_get_feat_names (),
267 em->l2_input_feat_next[GBP_SRC_CLASSIFY_PORT]);
272 VLIB_INIT_FUNCTION (gbp_src_classify_init);
275 * fd.io coding-style-patch-verification: ON
278 * eval: (c-set-style "gnu")