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>
21 #include <vnet/fib/fib_table.h>
22 #include <vnet/vxlan-gbp/vxlan_gbp_packet.h>
24 typedef enum gbp_src_classify_type_t_
26 GBP_SRC_CLASSIFY_NULL,
27 GBP_SRC_CLASSIFY_PORT,
28 } gbp_src_classify_type_t;
30 #define GBP_SRC_N_CLASSIFY (GBP_SRC_CLASSIFY_PORT + 1)
33 * Grouping of global data for the GBP source EPG classification feature
35 typedef struct gbp_src_classify_main_t_
38 * Next nodes for L2 output features
40 u32 l2_input_feat_next[GBP_SRC_N_CLASSIFY][32];
41 } gbp_src_classify_main_t;
43 static gbp_src_classify_main_t gbp_src_classify_main;
46 * per-packet trace data
48 typedef struct gbp_classify_trace_t_
50 /* per-pkt trace data */
52 } gbp_classify_trace_t;
55 * determine the SRC EPG form the input port
58 gbp_classify_inline (vlib_main_t * vm,
59 vlib_node_runtime_t * node,
61 gbp_src_classify_type_t type, dpo_proto_t dproto)
63 gbp_src_classify_main_t *gscm = &gbp_src_classify_main;
64 u32 n_left_from, *from, *to_next;
68 n_left_from = frame->n_vectors;
69 from = vlib_frame_vector_args (frame);
71 while (n_left_from > 0)
75 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
77 while (n_left_from > 0 && n_left_to_next > 0)
79 u32 next0, bi0, src_epg, sw_if_index0;
80 const gbp_endpoint_t *ge0;
90 b0 = vlib_get_buffer (vm, bi0);
92 sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
93 vnet_buffer2 (b0)->gbp.flags = VXLAN_GBP_GPFLAGS_NONE;
95 if (GBP_SRC_CLASSIFY_NULL == type)
97 src_epg = EPG_INVALID;
99 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
100 L2INPUT_FEAT_GBP_NULL_CLASSIFY);
104 if (DPO_PROTO_ETHERNET == dproto)
106 const ethernet_header_t *h0;
108 h0 = vlib_buffer_get_current (b0);
110 vnet_l2_feature_next (b0, gscm->l2_input_feat_next[type],
111 L2INPUT_FEAT_GBP_SRC_CLASSIFY);
112 ge0 = gbp_endpoint_find_mac (h0->src_address,
113 vnet_buffer (b0)->l2.bd_index);
115 else if (DPO_PROTO_IP4 == dproto)
117 const ip4_header_t *h0;
119 h0 = vlib_buffer_get_current (b0);
121 ge0 = gbp_endpoint_find_ip4
123 fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
128 * Go straight to looukp, do not pass go, do not collect $200
132 else if (DPO_PROTO_IP6 == dproto)
134 const ip6_header_t *h0;
136 h0 = vlib_buffer_get_current (b0);
138 ge0 = gbp_endpoint_find_ip6
140 fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP6,
145 * Go straight to lookup, do not pass go, do not collect $200
156 if (PREDICT_TRUE (NULL != ge0))
157 src_epg = ge0->ge_fwd.gef_epg_id;
159 src_epg = EPG_INVALID;
162 vnet_buffer2 (b0)->gbp.src_epg = src_epg;
164 if (PREDICT_FALSE ((b0->flags & VLIB_BUFFER_IS_TRACED)))
166 gbp_classify_trace_t *t =
167 vlib_add_trace (vm, node, b0, sizeof (*t));
168 t->src_epg = src_epg;
171 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
172 to_next, n_left_to_next,
176 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
179 return frame->n_vectors;
183 gbp_src_classify (vlib_main_t * vm,
184 vlib_node_runtime_t * node, vlib_frame_t * frame)
186 return (gbp_classify_inline (vm, node, frame,
187 GBP_SRC_CLASSIFY_PORT, DPO_PROTO_ETHERNET));
191 gbp_null_classify (vlib_main_t * vm,
192 vlib_node_runtime_t * node, vlib_frame_t * frame)
194 return (gbp_classify_inline (vm, node, frame,
195 GBP_SRC_CLASSIFY_NULL, DPO_PROTO_ETHERNET));
199 gbp_ip4_src_classify (vlib_main_t * vm,
200 vlib_node_runtime_t * node, vlib_frame_t * frame)
202 return (gbp_classify_inline (vm, node, frame,
203 GBP_SRC_CLASSIFY_PORT, DPO_PROTO_IP4));
207 gbp_ip6_src_classify (vlib_main_t * vm,
208 vlib_node_runtime_t * node, vlib_frame_t * frame)
210 return (gbp_classify_inline (vm, node, frame,
211 GBP_SRC_CLASSIFY_PORT, DPO_PROTO_IP6));
215 /* packet trace format function */
217 format_gbp_classify_trace (u8 * s, va_list * args)
219 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
220 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
221 gbp_classify_trace_t *t = va_arg (*args, gbp_classify_trace_t *);
223 s = format (s, "src-epg:%d", t->src_epg);
229 VLIB_REGISTER_NODE (gbp_null_classify_node) = {
230 .function = gbp_null_classify,
231 .name = "gbp-null-classify",
232 .vector_size = sizeof (u32),
233 .format_trace = format_gbp_classify_trace,
234 .type = VLIB_NODE_TYPE_INTERNAL,
240 VLIB_NODE_FUNCTION_MULTIARCH (gbp_null_classify_node, gbp_null_classify);
242 VLIB_REGISTER_NODE (gbp_src_classify_node) = {
243 .function = gbp_src_classify,
244 .name = "gbp-src-classify",
245 .vector_size = sizeof (u32),
246 .format_trace = format_gbp_classify_trace,
247 .type = VLIB_NODE_TYPE_INTERNAL,
253 VLIB_NODE_FUNCTION_MULTIARCH (gbp_src_classify_node, gbp_src_classify);
255 VLIB_REGISTER_NODE (gbp_ip4_src_classify_node) = {
256 .function = gbp_ip4_src_classify,
257 .name = "ip4-gbp-src-classify",
258 .vector_size = sizeof (u32),
259 .format_trace = format_gbp_classify_trace,
260 .type = VLIB_NODE_TYPE_INTERNAL,
269 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip4_src_classify_node, gbp_ip4_src_classify);
271 VLIB_REGISTER_NODE (gbp_ip6_src_classify_node) = {
272 .function = gbp_ip6_src_classify,
273 .name = "ip6-gbp-src-classify",
274 .vector_size = sizeof (u32),
275 .format_trace = format_gbp_classify_trace,
276 .type = VLIB_NODE_TYPE_INTERNAL,
285 VLIB_NODE_FUNCTION_MULTIARCH (gbp_ip6_src_classify_node, gbp_ip6_src_classify);
287 VNET_FEATURE_INIT (gbp_ip4_src_classify_feat_node, static) =
289 .arc_name = "ip4-unicast",
290 .node_name = "ip4-gbp-src-classify",
291 .runs_before = VNET_FEATURES ("nat44-out2in"),
293 VNET_FEATURE_INIT (gbp_ip6_src_classify_feat_node, static) =
295 .arc_name = "ip6-unicast",
296 .node_name = "ip6-gbp-src-classify",
297 .runs_before = VNET_FEATURES ("nat66-out2in"),
300 static clib_error_t *
301 gbp_src_classify_init (vlib_main_t * vm)
303 gbp_src_classify_main_t *em = &gbp_src_classify_main;
305 /* Initialize the feature next-node indexes */
306 feat_bitmap_init_next_nodes (vm,
307 gbp_src_classify_node.index,
309 l2input_get_feat_names (),
310 em->l2_input_feat_next[GBP_SRC_CLASSIFY_NULL]);
311 feat_bitmap_init_next_nodes (vm,
312 gbp_null_classify_node.index,
314 l2input_get_feat_names (),
315 em->l2_input_feat_next[GBP_SRC_CLASSIFY_PORT]);
320 VLIB_INIT_FUNCTION (gbp_src_classify_init);
323 * fd.io coding-style-patch-verification: ON
326 * eval: (c-set-style "gnu")