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;
87 b0 = vlib_get_buffer (vm, bi0);
89 sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
91 if (GBP_SRC_CLASSIFY_NULL == type)
93 src_epg = EPG_INVALID;
95 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
96 L2INPUT_FEAT_GBP_NULL_CLASSIFY);
100 src_epg = gbp_port_to_epg (sw_if_index0);
104 * Go straight to looukp, do not pass go, do not collect $200
111 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
112 L2INPUT_FEAT_GBP_SRC_CLASSIFY);
116 vnet_buffer2 (b0)->gbp.src_epg = src_epg;
118 if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED)))
120 gbp_classify_trace_t *t =
121 vlib_add_trace (vm, node, b0, sizeof (*t));
122 t->src_epg = src_epg;
125 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
126 to_next, n_left_to_next,
130 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
133 return frame->n_vectors;
137 gbp_src_classify (vlib_main_t * vm,
138 vlib_node_runtime_t * node, vlib_frame_t * frame)
140 return (gbp_classify_inline (vm, node, frame, GBP_SRC_CLASSIFY_PORT, 0));
144 gbp_null_classify (vlib_main_t * vm,
145 vlib_node_runtime_t * node, vlib_frame_t * frame)
147 return (gbp_classify_inline (vm, node, frame, GBP_SRC_CLASSIFY_NULL, 0));
151 gbp_ip4_src_classify (vlib_main_t * vm,
152 vlib_node_runtime_t * node, vlib_frame_t * frame)
154 return (gbp_classify_inline (vm, node, frame, 0, 1));
158 gbp_ip6_src_classify (vlib_main_t * vm,
159 vlib_node_runtime_t * node, vlib_frame_t * frame)
161 return (gbp_classify_inline (vm, node, frame, 0, 1));
165 /* packet trace format function */
167 format_gbp_classify_trace (u8 * s, va_list * args)
169 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
170 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
171 gbp_classify_trace_t *t = va_arg (*args, gbp_classify_trace_t *);
173 s = format (s, "src-epg:%d", t->src_epg);
179 VLIB_REGISTER_NODE (gbp_null_classify_node) = {
180 .function = gbp_null_classify,
181 .name = "gbp-null-classify",
182 .vector_size = sizeof (u32),
183 .format_trace = format_gbp_classify_trace,
184 .type = VLIB_NODE_TYPE_INTERNAL,
190 VLIB_NODE_FUNCTION_MULTIARCH (gbp_null_classify_node, gbp_null_classify);
192 VLIB_REGISTER_NODE (gbp_src_classify_node) = {
193 .function = gbp_src_classify,
194 .name = "gbp-src-classify",
195 .vector_size = sizeof (u32),
196 .format_trace = format_gbp_classify_trace,
197 .type = VLIB_NODE_TYPE_INTERNAL,
203 VLIB_NODE_FUNCTION_MULTIARCH (gbp_src_classify_node, gbp_src_classify);
205 VLIB_REGISTER_NODE (gbp_ip4_src_classify_node) = {
206 .function = gbp_ip4_src_classify,
207 .name = "ip4-gbp-src-classify",
208 .vector_size = sizeof (u32),
209 .format_trace = format_gbp_classify_trace,
210 .type = VLIB_NODE_TYPE_INTERNAL,
219 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip4_src_classify_node, gbp_ip4_src_classify);
221 VLIB_REGISTER_NODE (gbp_ip6_src_classify_node) = {
222 .function = gbp_ip6_src_classify,
223 .name = "ip6-gbp-src-classify",
224 .vector_size = sizeof (u32),
225 .format_trace = format_gbp_classify_trace,
226 .type = VLIB_NODE_TYPE_INTERNAL,
235 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip6_src_classify_node, gbp_ip6_src_classify);
237 VNET_FEATURE_INIT (gbp_ip4_src_classify_feat_node, static) =
239 .arc_name = "ip4-unicast",
240 .node_name = "ip4-gbp-src-classify",
241 .runs_before = VNET_FEATURES ("nat44-out2in"),
243 VNET_FEATURE_INIT (gbp_ip6_src_classify_feat_node, static) =
245 .arc_name = "ip6-unicast",
246 .node_name = "ip6-gbp-src-classify",
247 .runs_before = VNET_FEATURES ("nat66-out2in"),
250 static clib_error_t *
251 gbp_src_classify_init (vlib_main_t * vm)
253 gbp_src_classify_main_t *em = &gbp_src_classify_main;
255 /* Initialize the feature next-node indexes */
256 feat_bitmap_init_next_nodes (vm,
257 gbp_src_classify_node.index,
259 l2input_get_feat_names (),
260 em->l2_input_feat_next[GBP_SRC_CLASSIFY_NULL]);
261 feat_bitmap_init_next_nodes (vm,
262 gbp_null_classify_node.index,
264 l2input_get_feat_names (),
265 em->l2_input_feat_next[GBP_SRC_CLASSIFY_PORT]);
270 VLIB_INIT_FUNCTION (gbp_src_classify_init);
273 * fd.io coding-style-patch-verification: ON
276 * eval: (c-set-style "gnu")