FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
gbp_contract.h
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 #ifndef __GBP_CONTRACT_H__
17 #define __GBP_CONTRACT_H__
18 
19 #include <plugins/gbp/gbp.h>
20 #include <plugins/gbp/gbp_types.h>
21 
22 #define foreach_gbp_contract_error \
23  _(ALLOW_NO_SCLASS, "allow-no-sclass") \
24  _(ALLOW_INTRA, "allow-intra-sclass") \
25  _(ALLOW_A_BIT, "allow-a-bit-set") \
26  _(ALLOW_SCLASS_1, "allow-sclass-1") \
27  _(ALLOW_CONTRACT, "allow-contract") \
28  _(DROP_CONTRACT, "drop-contract") \
29  _(DROP_ETHER_TYPE, "drop-ether-type") \
30  _(DROP_NO_CONTRACT, "drop-no-contract") \
31  _(DROP_NO_DCLASS, "drop-no-dclass") \
32  _(DROP_NO_RULE, "drop-no-rule")
33 
34 typedef enum
35 {
36 #define _(sym,str) GBP_CONTRACT_ERROR_##sym,
38 #undef _
40 #define GBP_CONTRACT_N_ERROR GBP_CONTRACT_N_ERROR
42 
44 
45 /**
46  * The key for an Contract
47  */
48 typedef struct gbp_contract_key_t_
49 {
50  union
51  {
52  struct
53  {
55  /**
56  * source and destination EPGs for which the ACL applies
57  */
60  };
62  };
64 
65 typedef struct gbp_next_hop_t_
66 {
68  ip46_address_t gnh_ip;
77 
78 #define foreach_gbp_hash_mode \
79  _(SRC_IP, "src-ip") \
80  _(DST_IP, "dst-ip") \
81  _(SYMMETRIC, "symmetric")
82 
83 typedef enum gbp_hash_mode_t_
84 {
85 #define _(v,s) GBP_HASH_MODE_##v,
87 #undef _
89 
90 #define foreach_gbp_rule_action \
91  _(PERMIT, "permit") \
92  _(DENY, "deny") \
93  _(REDIRECT, "redirect")
94 
95 typedef enum gbp_rule_action_t_
96 {
97 #define _(v,s) GBP_RULE_##v,
99 #undef _
101 
102 #define foreach_gbp_policy_node \
103  _(L2, "L2") \
104  _(IP4, "ip4") \
105  _(IP6, "ip6")
106 
107 typedef enum gbp_policy_node_t_
108 {
109 #define _(v,s) GBP_POLICY_NODE_##v,
111 #undef _
113 #define GBP_POLICY_N_NODES (GBP_POLICY_NODE_IP6+1)
114 
115 #define FOR_EACH_GBP_POLICY_NODE(pnode) \
116  for (pnode = GBP_POLICY_NODE_L2; pnode < GBP_POLICY_N_NODES; pnode++)
117 
118 typedef struct gbp_rule_t_
119 {
123 
124  /**
125  * DPO of the load-balance object used to redirect
126  */
128 } gbp_rule_t;
129 
130 /**
131  * A Group Based Policy Contract.
132  * Determines the ACL that applies to traffic pass between two endpoint groups
133  */
134 typedef struct gbp_contract_t_
135 {
136  /**
137  * source and destination EPGs
138  */
140 
143 
144  /**
145  * The ACL to apply for packets from the source to the destination EPG
146  */
148 
149  /**
150  * An ethertype whitelist
151  */
154 
155 /**
156  * EPG src,dst pair to ACL mapping table, aka contract DB
157  */
158 typedef struct gbp_contract_db_t_
159 {
160  /**
161  * We can form a u64 key from the pair, so use a simple hash table
162  */
165 
169  u32 acl_index,
170  index_t * rules,
173  sclass_t dclass);
174 
176  gbp_hash_mode_t hash_mode, index_t * nhs);
177 extern void gbp_rule_free (index_t gui);
178 extern index_t gbp_next_hop_alloc (const ip46_address_t * ip,
179  index_t grd,
180  const mac_address_t * mac, index_t gbd);
181 
182 typedef int (*gbp_contract_cb_t) (gbp_contract_t * gbpe, void *ctx);
183 extern void gbp_contract_walk (gbp_contract_cb_t bgpe, void *ctx);
184 
185 extern u8 *format_gbp_rule_action (u8 * s, va_list * args);
186 extern u8 *format_gbp_contract (u8 * s, va_list * args);
187 
188 /**
189  * DP functions and databases
190  */
192 
195 {
196  uword *p;
197 
198  p = hash_get (gbp_contract_db.gc_hash, key->as_u64);
199 
200  if (NULL != p)
201  return (p[0]);
202 
203  return (INDEX_INVALID);
204 }
205 
207 
210 {
211  return (pool_elt_at_index (gbp_contract_pool, gci));
212 }
213 
214 extern gbp_rule_t *gbp_rule_pool;
215 
218 {
219  return (pool_elt_at_index (gbp_rule_pool, gui));
220 }
221 
224 
225 typedef enum
226 {
231 
235  gbp_rule_t ** rule, u32 * intra, u32 * sclass1,
236  u32 * acl_match, u32 * rule_match,
237  gbp_contract_error_t * err,
239 {
240  fa_5tuple_opaque_t fa_5tuple;
241  const gbp_contract_t *contract;
242  index_t contract_index;
243  u32 acl_pos, trace_bitmap;
244  u16 etype;
245  u8 ip6, action;
246 
247  *rule = 0;
248  trace_bitmap = 0;
249 
250  if (key->gck_src == key->gck_dst)
251  {
252  /* intra-epg allowed */
253  (*intra)++;
254  *err = GBP_CONTRACT_ERROR_ALLOW_INTRA;
255  return GBP_RULE_PERMIT;
256  }
257 
258  if (1 == key->gck_src || 1 == key->gck_dst)
259  {
260  /* sclass 1 allowed */
261  (*sclass1)++;
262  *err = GBP_CONTRACT_ERROR_ALLOW_SCLASS_1;
263  return GBP_RULE_PERMIT;
264  }
265 
266  /* look for contract */
267  contract_index = gbp_contract_find (key);
268  if (INDEX_INVALID == contract_index)
269  {
270  *err = GBP_CONTRACT_ERROR_DROP_NO_CONTRACT;
271  return GBP_RULE_DENY;
272  }
273 
274  contract = gbp_contract_get (contract_index);
275 
276  *err = GBP_CONTRACT_ERROR_DROP_CONTRACT;
277 
278  switch (type)
279  {
281  ip6 = 0;
282  break;
284  ip6 = 1;
285  break;
287  {
288  /* check ethertype */
289  etype =
290  ((u16 *) (vlib_buffer_get_current (b) +
291  vnet_buffer (b)->l2.l2_len))[-1];
292 
293  if (~0 == vec_search (contract->gc_allowed_ethertypes, etype))
294  {
295  *err = GBP_CONTRACT_ERROR_DROP_ETHER_TYPE;
296  goto contract_deny;
297  }
298 
299  switch (clib_net_to_host_u16 (etype))
300  {
301  case ETHERNET_TYPE_IP4:
302  ip6 = 0;
303  break;
304  case ETHERNET_TYPE_IP6:
305  ip6 = 1;
306  break;
307  default:
308  goto contract_deny;
309  }
310  }
311  break;
312  }
313 
314  /* check ACL */
315  action = 0;
316  acl_plugin_fill_5tuple_inline (gm->acl_plugin.p_acl_main,
317  contract->gc_lc_index, b, ip6,
318  GBP_CONTRACT_APPLY_L2 != type /* input */ ,
319  GBP_CONTRACT_APPLY_L2 == type /* l2_path */ ,
320  &fa_5tuple);
321  acl_plugin_match_5tuple_inline (gm->acl_plugin.p_acl_main,
322  contract->gc_lc_index, &fa_5tuple, ip6,
323  &action, &acl_pos, acl_match, rule_match,
324  &trace_bitmap);
325  if (action <= 0)
326  goto contract_deny;
327 
328  if (PREDICT_FALSE (*rule_match >= vec_len (contract->gc_rules)))
329  {
330  *err = GBP_CONTRACT_ERROR_DROP_NO_RULE;
331  goto contract_deny;
332  }
333 
334  *rule = gbp_rule_get (contract->gc_rules[*rule_match]);
335  switch ((*rule)->gu_action)
336  {
337  case GBP_RULE_PERMIT:
338  case GBP_RULE_REDIRECT:
339  *err = GBP_CONTRACT_ERROR_ALLOW_CONTRACT;
341  vm->thread_index, contract_index, 1,
343  return (*rule)->gu_action;
344  case GBP_RULE_DENY:
345  break;
346  }
347 
348 contract_deny:
350  vm->thread_index, contract_index, 1,
352  return GBP_RULE_DENY;
353 }
354 
355 #endif /* __GBP_CONTRACT_H__ */
356 /*
357  * fd.io coding-style-patch-verification: ON
358  *
359  * Local Variables:
360  * eval: (c-set-style "gnu")
361  * End:
362  */
stats_index
u32 stats_index
Definition: ip.api:145
GBP_CONTRACT_APPLY_IP4
@ GBP_CONTRACT_APPLY_IP4
Definition: gbp_contract.h:228
gbp_contract_t_::gc_acl_index
u32 gc_acl_index
Definition: gbp_contract.h:141
gbp_next_hop_t_::gnh_ge
u32 gnh_ge
Definition: gbp_contract.h:73
gbp_contract_cb_t
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:182
mac
vl_api_mac_address_t mac
Definition: l2.api:559
acl_plugin_match_5tuple_inline
static int acl_plugin_match_5tuple_inline(void *p_acl_main, u32 lc_index, fa_5tuple_opaque_t *pkt_5tuple, int is_ip6, u8 *r_action, u32 *r_acl_pos_p, u32 *r_acl_match_p, u32 *r_rule_match_p, u32 *trace_bitmap)
Definition: public_inlines.h:653
gbp_next_hop_t_::gnh_rd
index_t gnh_rd
Definition: gbp_contract.h:72
gbp_contract_pool
gbp_contract_t * gbp_contract_pool
Definition: gbp_contract.c:38
gbp_policy_node_t
enum gbp_policy_node_t_ gbp_policy_node_t
gbp_contract_find
static index_t gbp_contract_find(gbp_contract_key_t *key)
Definition: gbp_contract.h:194
gbp_types.h
GBP_CONTRACT_N_ERROR
#define GBP_CONTRACT_N_ERROR
Definition: gbp_contract.h:40
gbp_rule_get
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:217
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
gbp_contract_t_::gc_key
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:139
gbp_rule_free
void gbp_rule_free(index_t gui)
Definition: gbp_contract.c:77
gbp_next_hop_t_
Definition: gbp_contract.h:65
gbp.h
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
gbp_contract_drop_counters
vlib_combined_counter_main_t gbp_contract_drop_counters
Definition: gbp_contract.c:56
nhs
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:313
gbp_contract_apply_type_t
gbp_contract_apply_type_t
Definition: gbp_contract.h:225
gbp_contract_delete
int gbp_contract_delete(gbp_scope_t scope, sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:536
allowed_ethertypes
u16 allowed_ethertypes[16]
Definition: gbp.api:336
gbp_rule_t_::gu_nhs
index_t * gu_nhs
Definition: gbp_contract.h:122
vlib_buffer_length_in_chain
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:433
gbp_contract_db_t
struct gbp_contract_db_t_ gbp_contract_db_t
EPG src,dst pair to ACL mapping table, aka contract DB.
format_gbp_rule_action
u8 * format_gbp_rule_action(u8 *s, va_list *args)
Definition: gbp_contract.c:171
rule_match
vlib_parse_match_function_t rule_match
Definition: parse.h:189
key
typedef key
Definition: ipsec_types.api:88
gbp_rule_action_t_
gbp_rule_action_t_
Definition: gbp_contract.h:95
gbp_policy_node_t_
gbp_policy_node_t_
Definition: gbp_contract.h:107
gbp_rule_pool
gbp_rule_t * gbp_rule_pool
Definition: gbp_contract.c:44
fa_5tuple_opaque_t
Definition: exported_types.h:25
gbp_hash_mode_t
enum gbp_hash_mode_t_ gbp_hash_mode_t
gbp_next_hop_t_::gnh_node
fib_node_t gnh_node
Definition: gbp_contract.h:67
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
gbp_contract_error_t
gbp_contract_error_t
Definition: gbp_contract.h:34
gbp_contract_t
struct gbp_contract_t_ gbp_contract_t
A Group Based Policy Contract.
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
FIB_PROTOCOL_IP_MAX
#define FIB_PROTOCOL_IP_MAX
Definition outside of enum so it does not need to be included in non-defaulted switch statements.
Definition: fib_types.h:57
gbp_contract_key_t_::gck_scope
gbp_scope_t gck_scope
Definition: gbp_contract.h:54
gbp_contract_db
gbp_contract_db_t gbp_contract_db
DP functions and databases.
Definition: gbp_contract.c:36
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
gbp_next_hop_t_::gnh_bd
index_t gnh_bd
Definition: gbp_contract.h:71
gbp_contract_key_t
struct gbp_contract_key_t_ gbp_contract_key_t
The key for an Contract.
gbp_contract_permit_counters
vlib_combined_counter_main_t gbp_contract_permit_counters
Definition: gbp_contract.c:51
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
static_always_inline
#define static_always_inline
Definition: clib.h:112
gbp_hash_mode_t_
gbp_hash_mode_t_
Definition: gbp_contract.h:83
gbp_contract_walk
void gbp_contract_walk(gbp_contract_cb_t bgpe, void *ctx)
Definition: gbp_contract.c:565
gbp_next_hop_t_::gnh_mac
mac_address_t gnh_mac
Definition: gbp_contract.h:69
uword
u64 uword
Definition: types.h:112
gbp_contract_db_t_::gc_hash
uword * gc_hash
We can form a u64 key from the pair, so use a simple hash table.
Definition: gbp_contract.h:163
hash_get
#define hash_get(h, key)
Definition: hash.h:249
gbp_rule_t
struct gbp_rule_t_ gbp_rule_t
gbp_next_hop_alloc
index_t gbp_next_hop_alloc(const ip46_address_t *ip, index_t grd, const mac_address_t *mac, index_t gbd)
Definition: gbp_contract.c:83
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:213
scope
vl_api_gbp_scope_t scope
Definition: gbp.api:78
foreach_gbp_policy_node
#define foreach_gbp_policy_node
Definition: gbp_contract.h:102
gbp_contract_key_t_::gck_src
sclass_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:58
sclass
u16 sclass
Definition: gbp.api:131
acl_index
u32 acl_index
Definition: abf.api:60
gbp_contract_key_t_::as_u64
u64 as_u64
Definition: gbp_contract.h:61
GBP_POLICY_N_NODES
#define GBP_POLICY_N_NODES
Definition: gbp_contract.h:113
gbp_next_hop_t_::gnh_ai
index_t gnh_ai[FIB_PROTOCOL_IP_MAX]
Definition: gbp_contract.h:75
vec_search
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
Definition: vec.h:1054
GBP_CONTRACT_APPLY_L2
@ GBP_CONTRACT_APPLY_L2
Definition: gbp_contract.h:227
gm
#define gm
Definition: dlmalloc.c:1219
gbp_contract_db_t_
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp_contract.h:158
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
dclass
u16 dclass
Definition: gbp.api:333
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
gbp_rule_action_t
enum gbp_rule_action_t_ gbp_rule_action_t
format_gbp_contract
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:650
gbp_contract_t_::gc_lc_index
u32 gc_lc_index
Definition: gbp_contract.h:142
sclass_t
u16 sclass_t
Definition: gbp_types.h:25
gbp_next_hop_t_::gnh_sibling
u32 gnh_sibling
Definition: gbp_contract.h:74
u64
unsigned long u64
Definition: types.h:89
gbp_rule_t_
Definition: gbp_contract.h:118
vlib_combined_counter_main_t
A collection of combined counters.
Definition: counter.h:203
foreach_gbp_rule_action
#define foreach_gbp_rule_action
Definition: gbp_contract.h:90
acl_plugin_fill_5tuple_inline
static void acl_plugin_fill_5tuple_inline(void *p_acl_main, u32 lc_index, vlib_buffer_t *b0, int is_ip6, int is_input, int is_l2_path, fa_5tuple_opaque_t *p5tuple_pkt)
Definition: public_inlines.h:231
gbp_contract_update
int gbp_contract_update(gbp_scope_t scope, sclass_t sclass, sclass_t dclass, u32 acl_index, index_t *rules, u16 *allowed_ethertypes, u32 *stats_index)
Definition: gbp_contract.c:465
u32
unsigned int u32
Definition: types.h:88
gbp_rule_t_::gu_hash_mode
gbp_hash_mode_t gu_hash_mode
Definition: gbp_contract.h:121
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
gbp_next_hop_t_::gnh_ip
ip46_address_t gnh_ip
Definition: gbp_contract.h:68
rules
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:338
gbp_next_hop_t_::gnh_gu
index_t gnh_gu
Definition: gbp_contract.h:70
foreach_gbp_hash_mode
#define foreach_gbp_hash_mode
Definition: gbp_contract.h:78
GBP_CONTRACT_APPLY_IP6
@ GBP_CONTRACT_APPLY_IP6
Definition: gbp_contract.h:229
gbp_contract_error_strings
char * gbp_contract_error_strings[GBP_CONTRACT_N_ERROR]
Definition: gbp_contract.c:27
mac_address_t_
Definition: mac_address.h:21
fib_node_t_
An node in the FIB graph.
Definition: fib_node.h:301
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
gbp_contract_get
static gbp_contract_t * gbp_contract_get(index_t gci)
Definition: gbp_contract.h:209
vlib_main_t
Definition: main.h:102
gbp_contract_t_::gc_rules
index_t * gc_rules
The ACL to apply for packets from the source to the destination EPG.
Definition: gbp_contract.h:147
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
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
ip
vl_api_address_t ip
Definition: l2.api:558
gbp_rule_alloc
index_t gbp_rule_alloc(gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t *nhs)
Definition: gbp_contract.c:62
gbp_contract_t_
A Group Based Policy Contract.
Definition: gbp_contract.h:134
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
gbp_contract_t_::gc_allowed_ethertypes
u16 * gc_allowed_ethertypes
An ethertype whitelist.
Definition: gbp_contract.h:152
gbp_contract_key_t_::gck_dst
sclass_t gck_dst
Definition: gbp_contract.h:59
foreach_gbp_contract_error
#define foreach_gbp_contract_error
Definition: gbp_contract.h:22
INDEX_INVALID
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
action
vl_api_mac_event_action_t action
Definition: l2.api:211
gbp_main_t
Group Base Policy (GBP) defines:
Definition: gbp.h:42
gbp_scope_t
u16 gbp_scope_t
Definition: gbp_types.h:24
gbp_rule_t_::gu_action
gbp_rule_action_t gu_action
Definition: gbp_contract.h:120
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
gbp_next_hop_t
struct gbp_next_hop_t_ gbp_next_hop_t