FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
gbp_policy_node.c
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 
16 #include <plugins/gbp/gbp.h>
18 #include <plugins/gbp/gbp_policy.h>
23 
26 
27 typedef enum
28 {
32 
35 {
36  etype = clib_net_to_host_u16 (etype);
37 
38  switch (etype)
39  {
40  case ETHERNET_TYPE_IP4:
41  return (DPO_PROTO_IP4);
42  case ETHERNET_TYPE_IP6:
43  return (DPO_PROTO_IP6);
44  }
45 
46  return (DPO_PROTO_NONE);
47 }
48 
51 {
52  const ethernet_header_t *eth0;
53  const dpo_id_t *dpo;
54  dpo_proto_t dproto;
55 
56  eth0 = vlib_buffer_get_current (b0);
57  /* pop the ethernet header to prepare for L3 rewrite */
58  vlib_buffer_advance (b0, vnet_buffer (b0)->l2.l2_len);
59 
60  dproto = ethertype_to_dpo_proto (eth0->type);
61  dpo = &gu->gu_dpo[GBP_POLICY_NODE_L2][dproto];
62 
63  /* save the LB index for the next node and reset the IP flow hash
64  * so it's recalculated */
65  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo->dpoi_index;
66  vnet_buffer (b0)->ip.flow_hash = 0;
67 
68  return (dpo->dpoi_next_node);
69 }
70 
73  const gbp_policy_type_t type)
74 {
75  u32 feat_bit;
76 
77  switch (type)
78  {
79  case GBP_POLICY_PORT:
80  feat_bit = L2OUTPUT_FEAT_GBP_POLICY_PORT;
81  break;
82  case GBP_POLICY_MAC:
83  feat_bit = L2OUTPUT_FEAT_GBP_POLICY_MAC;
84  break;
85  case GBP_POLICY_LPM:
86  feat_bit = L2OUTPUT_FEAT_GBP_POLICY_LPM;
87  break;
88  default:
89  return GBP_POLICY_NEXT_DROP;
90  }
91 
92  return vnet_l2_feature_next (b, gpm->l2_output_feat_next[type], feat_bit);
93 }
94 
95 static uword
99 {
100  gbp_main_t *gm = &gbp_main;
102  u32 n_left_from, *from, *to_next;
103  u32 next_index;
104  u32 n_allow_intra, n_allow_a_bit, n_allow_sclass_1;
105 
106  next_index = 0;
107  n_left_from = frame->n_vectors;
109  n_allow_intra = n_allow_a_bit = n_allow_sclass_1 = 0;
110 
111  while (n_left_from > 0)
112  {
113  u32 n_left_to_next;
114 
115  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
116 
117  while (n_left_from > 0 && n_left_to_next > 0)
118  {
119  gbp_rule_action_t action0 = GBP_RULE_DENY;
120  const ethernet_header_t *h0;
121  const gbp_endpoint_t *ge0;
123  u32 acl_match = ~0, rule_match = ~0;
124  gbp_policy_next_t next0;
125  gbp_contract_key_t key0;
126  u32 bi0, sw_if_index0;
127  vlib_buffer_t *b0;
128  gbp_rule_t *rule0;
129 
130  next0 = GBP_POLICY_NEXT_DROP;
131  bi0 = from[0];
132  to_next[0] = bi0;
133  from += 1;
134  to_next += 1;
135  n_left_from -= 1;
136  n_left_to_next -= 1;
137 
138  b0 = vlib_get_buffer (vm, bi0);
139  h0 = vlib_buffer_get_current (b0);
140  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
141 
142  /*
143  * Reflection check; in and out on an ivxlan tunnel
144  */
145  if ((~0 != vxlan_gbp_tunnel_by_sw_if_index (sw_if_index0)) &&
146  (vnet_buffer2 (b0)->gbp.flags & VXLAN_GBP_GPFLAGS_R))
147  {
148  goto trace;
149  }
150 
151  /*
152  * If the A-bit is set then policy has already been applied
153  * and we skip enforcement here.
154  */
155  if (vnet_buffer2 (b0)->gbp.flags & VXLAN_GBP_GPFLAGS_A)
156  {
157  next0 = gbp_policy_l2_feature_next (gpm, b0, type);
158  n_allow_a_bit++;
159  key0.as_u64 = ~0;
160  goto trace;
161  }
162 
163  /*
164  * determine the src and dst EPG
165  */
166 
167  /* zero out the key to ensure the pad space is clear */
168  key0.as_u64 = 0;
169  key0.gck_src = vnet_buffer2 (b0)->gbp.sclass;
170  key0.gck_dst = SCLASS_INVALID;
171 
172  if (GBP_POLICY_LPM == type)
173  {
174  const ip4_address_t *ip4 = 0;
175  const ip6_address_t *ip6 = 0;
176  const dpo_proto_t proto =
180  {
181  const gbp_ext_itf_t *ext_itf =
182  gbp_ext_itf_get (sw_if_index0);
183  const gbp_policy_dpo_t *gpd =
185  ext_itf->gx_fib_index[proto]);
186  if (gpd)
187  key0.gck_dst = gpd->gpd_sclass;
188  }
189  }
190  else
191  {
192  if (GBP_POLICY_PORT == type)
193  ge0 = gbp_endpoint_find_itf (sw_if_index0);
194  else
196  vnet_buffer (b0)->l2.bd_index);
197  if (NULL != ge0)
198  key0.gck_dst = ge0->ge_fwd.gef_sclass;
199  }
200 
201  if (SCLASS_INVALID == key0.gck_dst)
202  {
203  /* If you cannot determine the destination EP then drop */
204  b0->error = node->errors[GBP_CONTRACT_ERROR_DROP_NO_DCLASS];
205  goto trace;
206  }
207 
208  key0.gck_src = vnet_buffer2 (b0)->gbp.sclass;
209  if (SCLASS_INVALID == key0.gck_src)
210  {
211  /*
212  * the src EPG is not set when the packet arrives on an EPG
213  * uplink interface and we do not need to apply policy
214  */
215  next0 = gbp_policy_l2_feature_next (gpm, b0, type);
216  goto trace;
217  }
218 
219  key0.gck_scope =
220  gbp_bridge_domain_get_scope (vnet_buffer (b0)->l2.bd_index);
221 
222  action0 =
223  gbp_contract_apply (vm, gm, &key0, b0, &rule0, &n_allow_intra,
224  &n_allow_sclass_1, &acl_match, &rule_match,
225  &err0, GBP_CONTRACT_APPLY_L2);
226  switch (action0)
227  {
228  case GBP_RULE_PERMIT:
229  next0 = gbp_policy_l2_feature_next (gpm, b0, type);
230  vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A;
231  break;
232  case GBP_RULE_REDIRECT:
233  next0 = gbp_rule_l2_redirect (rule0, b0);
234  vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A;
235  break;
236  case GBP_RULE_DENY:
237  next0 = GBP_POLICY_NEXT_DROP;
238  b0->error = node->errors[err0];
239  break;
240  }
241 
242  trace:
243  gbp_policy_trace (vm, node, b0, &key0, action0, acl_match,
244  rule_match);
245 
246  /* verify speculative enqueue, maybe switch current next frame */
248  to_next, n_left_to_next,
249  bi0, next0);
250  }
251 
252  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
253  }
254 
255  vlib_node_increment_counter (vm, node->node_index,
256  GBP_CONTRACT_ERROR_ALLOW_INTRA, n_allow_intra);
257  vlib_node_increment_counter (vm, node->node_index,
258  GBP_CONTRACT_ERROR_ALLOW_A_BIT, n_allow_a_bit);
259  vlib_node_increment_counter (vm, node->node_index,
260  GBP_CONTRACT_ERROR_ALLOW_SCLASS_1,
261  n_allow_sclass_1);
262 
263  return frame->n_vectors;
264 }
265 
269 {
271 }
272 
276 {
278 }
279 
283 {
285 }
286 
287 /* *INDENT-OFF* */
289  .name = "gbp-policy-port",
290  .vector_size = sizeof (u32),
291  .format_trace = format_gbp_policy_trace,
293 
295  .error_strings = gbp_contract_error_strings,
296 
297  .n_next_nodes = GBP_POLICY_N_NEXT,
298  .next_nodes = {
299  [GBP_POLICY_NEXT_DROP] = "error-drop",
300  },
301 };
302 
304  .name = "gbp-policy-mac",
305  .vector_size = sizeof (u32),
306  .format_trace = format_gbp_policy_trace,
308 
310  .error_strings = gbp_contract_error_strings,
311 
312  .n_next_nodes = GBP_POLICY_N_NEXT,
313  .next_nodes = {
314  [GBP_POLICY_NEXT_DROP] = "error-drop",
315  },
316 };
317 
319  .name = "gbp-policy-lpm",
320  .vector_size = sizeof (u32),
321  .format_trace = format_gbp_policy_trace,
323 
325  .error_strings = gbp_contract_error_strings,
326 
327  .n_next_nodes = GBP_POLICY_N_NEXT,
328  .next_nodes = {
329  [GBP_POLICY_NEXT_DROP] = "error-drop",
330  },
331 };
332 
333 /* *INDENT-ON* */
334 
335 /*
336  * fd.io coding-style-patch-verification: ON
337  *
338  * Local Variables:
339  * eval: (c-set-style "gnu")
340  * End:
341  */
gpb_ext_itf_t_::gx_fib_index
u32 gx_fib_index[DPO_PROTO_NUM]
cached FIB indices from the RD
Definition: gbp_ext_itf.h:53
dpo_id_t_::dpoi_next_node
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:186
trace
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
Definition: vlib_api_cli.c:870
gbp_policy_dpo.h
dpo_id_t_::dpoi_index
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:190
gbp_endpoint_t_::ge_fwd
gbp_endpoint_fwd_t ge_fwd
Definition: gbp_endpoint.h:208
gbp_policy_port_node
vlib_node_registration_t gbp_policy_port_node
(constructor) VLIB_REGISTER_NODE (gbp_policy_port_node)
Definition: gbp_policy_node.c:288
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
gbp_rule_l2_redirect
static u32 gbp_rule_l2_redirect(const gbp_rule_t *gu, vlib_buffer_t *b0)
Definition: gbp_policy_node.c:50
gbp_policy.h
gbp_policy_lpm_node
vlib_node_registration_t gbp_policy_lpm_node
(constructor) VLIB_REGISTER_NODE (gbp_policy_lpm_node)
Definition: gbp_policy_node.c:318
GBP_POLICY_PORT
@ GBP_POLICY_PORT
Definition: gbp.h:52
vxlan_gbp_tunnel_by_sw_if_index
static u32 vxlan_gbp_tunnel_by_sw_if_index(u32 sw_if_index)
Definition: vxlan_gbp.h:232
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
gbp_endpoint_fwd_t_::gef_sclass
sclass_t gef_sclass
Endpoint Group's sclass.
Definition: gbp_endpoint.h:172
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
dpo_proto_t
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
SCLASS_INVALID
#define SCLASS_INVALID
Definition: gbp_types.h:26
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
ethernet_header_t::dst_address
u8 dst_address[6]
Definition: packet.h:55
gbp_contract_error_strings
char * gbp_contract_error_strings[]
Definition: gbp_contract.c:27
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
gbp_classify.h
GBP_CLASSIFY_GET_IP_DST
@ GBP_CLASSIFY_GET_IP_DST
Definition: gbp_classify.h:50
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
GBP_POLICY_N_NEXT
@ GBP_POLICY_N_NEXT
Definition: gbp_policy_node.c:30
GBP_POLICY_LPM
@ GBP_POLICY_LPM
Definition: gbp.h:54
gbp.h
GBP_POLICY_MAC
@ GBP_POLICY_MAC
Definition: gbp.h:53
u16
unsigned short u16
Definition: types.h:57
gbp_policy_trace
static_always_inline void gbp_policy_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, const gbp_contract_key_t *key, gbp_rule_action_t action, u32 acl_match, u32 rule_match)
Definition: gbp_policy.h:40
ethernet_header_t::type
u16 type
Definition: packet.h:59
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vnet_buffer2
#define vnet_buffer2(b)
Definition: buffer.h:505
gbp_bridge_domain_get_scope
static gbp_scope_t gbp_bridge_domain_get_scope(u32 bd_index)
Definition: gbp_bridge_domain.h:143
vlib_frame_t
Definition: node.h:372
rule_match
vlib_parse_match_function_t rule_match
Definition: parse.h:189
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
gbp_ext_itf.h
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
gbp_contract_error_t
gbp_contract_error_t
Definition: gbp_contract.h:34
gbp_main
gbp_main_t gbp_main
Definition: gbp_api.c:46
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
gbp_policy_inline
static uword gbp_policy_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, const gbp_policy_type_t type)
Definition: gbp_policy_node.c:96
gbp_endpoint_find_mac
static_always_inline gbp_endpoint_t * gbp_endpoint_find_mac(const u8 *mac, u32 bd_index)
Definition: gbp_endpoint.h:279
gbp_policy_dpo_t_::gpd_sclass
sclass_t gpd_sclass
SClass.
Definition: gbp_policy_dpo.h:41
gbp_contract.h
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
gbp_contract_key_t_::gck_scope
gbp_scope_t gck_scope
Definition: gbp_contract.h:54
gbp_policy_dpo_t_
The GBP FWD DPO.
Definition: gbp_policy_dpo.h:29
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
gbp_policy_main_t_::l2_output_feat_next
u32 l2_output_feat_next[GBP_N_POLICY][32]
Next nodes for L2 output features.
Definition: gbp.h:67
static_always_inline
#define static_always_inline
Definition: clib.h:112
uword
u64 uword
Definition: types.h:112
ethernet_header_t
Definition: packet.h:52
gbp_policy_type_t
enum gbp_policy_type_t_ gbp_policy_type_t
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
gbp_contract_key_t_::gck_src
sclass_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:58
gbp_policy_mac_node
vlib_node_registration_t gbp_policy_mac_node
(constructor) VLIB_REGISTER_NODE (gbp_policy_mac_node)
Definition: gbp_policy_node.c:303
gbp_policy_next_t
gbp_policy_next_t
Definition: gbp_policy_node.c:27
ip4_address_t
Definition: ip4_packet.h:50
gbp_contract_key_t_::as_u64
u64 as_u64
Definition: gbp_contract.h:61
vxlan_gbp_packet.h
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
gbp_bridge_domain.h
gbp_ext_itf_get
static gbp_ext_itf_t * gbp_ext_itf_get(u32 sw_if_index)
Definition: gbp_ext_itf.h:79
GBP_CONTRACT_APPLY_L2
@ GBP_CONTRACT_APPLY_L2
Definition: gbp_contract.h:227
gm
#define gm
Definition: dlmalloc.c:1219
vnet_l2_feature_next
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
Definition: feat_bitmap.h:94
gbp_contract_apply
static_always_inline gbp_rule_action_t gbp_contract_apply(vlib_main_t *vm, gbp_main_t *gm, gbp_contract_key_t *key, vlib_buffer_t *b, gbp_rule_t **rule, u32 *intra, u32 *sclass1, u32 *acl_match, u32 *rule_match, gbp_contract_error_t *err, gbp_contract_apply_type_t type)
Definition: gbp_contract.h:233
vlib_validate_buffer_enqueue_x1
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
gbp_rule_action_t
enum gbp_rule_action_t_ gbp_rule_action_t
gbp_policy_next_t
gbp_policy_next_t
Definition: gbp_policy_dpo.c:225
gbp_rule_t_
Definition: gbp_contract.h:118
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
DPO_PROTO_IP6
@ DPO_PROTO_IP6
Definition: dpo.h:65
gbp_policy_main_t_
Grouping of global data for the GBP source EPG classification feature.
Definition: gbp.h:62
u32
unsigned int u32
Definition: types.h:88
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
DPO_PROTO_NONE
#define DPO_PROTO_NONE
Definition: dpo.h:73
gbp_rule_t_::gu_dpo
dpo_id_t gu_dpo[GBP_POLICY_N_NODES][FIB_PROTOCOL_IP_MAX]
DPO of the load-balance object used to redirect.
Definition: gbp_contract.h:127
gbp_contract_key_t_
The key for an Contract.
Definition: gbp_contract.h:48
vlib_main_t
Definition: main.h:102
gbp_policy_l2_feature_next
static_always_inline gbp_policy_next_t gbp_policy_l2_feature_next(gbp_policy_main_t *gpm, vlib_buffer_t *b, const gbp_policy_type_t type)
Definition: gbp_policy_node.c:72
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
gbp_classify_get_gpd
const static_always_inline gbp_policy_dpo_t * gbp_classify_get_gpd(const ip4_address_t *ip4, const ip6_address_t *ip6, const u32 fib_index)
Definition: gbp_policy_dpo.h:88
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
GBP_POLICY_NEXT_DROP
@ GBP_POLICY_NEXT_DROP
Definition: gbp_policy_node.c:29
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
gpb_ext_itf_t_
An external interface maps directly to an oflex L3ExternalInterface.
Definition: gbp_ext_itf.h:33
gbp_contract_key_t_::gck_dst
sclass_t gck_dst
Definition: gbp_contract.h:59
gbp_endpoint_t_
A Group Based Policy Endpoint.
Definition: gbp_endpoint.h:190
vlib_node_runtime_t
Definition: node.h:454
proto
vl_api_ip_proto_t proto
Definition: acl_types.api:51
ethertype_to_dpo_proto
static dpo_proto_t ethertype_to_dpo_proto(u16 etype)
Definition: gbp_policy_node.c:34
from
from
Definition: nat44_ei_hairpinning.c:415
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
format_gbp_policy_trace
u8 * format_gbp_policy_trace(u8 *s, va_list *args)
Definition: gbp_policy.c:24
vlib_get_next_frame
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:395
gbp_main_t
Group Base Policy (GBP) defines:
Definition: gbp.h:42
gbp_endpoint_find_itf
static_always_inline gbp_endpoint_t * gbp_endpoint_find_itf(u32 sw_if_index)
Definition: gbp_endpoint.h:355
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
gbp_classify_get_ip_address
static_always_inline dpo_proto_t gbp_classify_get_ip_address(const ethernet_header_t *eh0, const ip4_address_t **ip4, const ip6_address_t **ip6, const enum gbp_classify_get_ip_way way)
Definition: gbp_classify.h:54
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vxlan_gbp.h
gbp_policy_main
gbp_policy_main_t gbp_policy_main
Definition: gbp_policy.c:20
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169