FD.io VPP  v20.09-64-g4f7b92f0a
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;
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);
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;
340  vlib_increment_combined_counter (&gbp_contract_permit_counters,
341  vm->thread_index, contract_index, 1,
343  return (*rule)->gu_action;
344  case GBP_RULE_DENY:
345  break;
346  }
347 
348 contract_deny:
349  vlib_increment_combined_counter (&gbp_contract_drop_counters,
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  */
u16 * gc_allowed_ethertypes
An ethertype whitelist.
Definition: gbp_contract.h:152
#define GBP_CONTRACT_N_ERROR
Definition: gbp_contract.h:40
void gbp_rule_free(index_t gui)
Definition: gbp_contract.c:77
u32 acl_index
Definition: abf.api:60
u16 sclass_t
Definition: gbp_types.h:25
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:139
vl_api_mac_address_t mac
Definition: l2.api:502
fib_node_t gnh_node
Definition: gbp_contract.h:67
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:220
struct gbp_next_hop_t_ gbp_next_hop_t
struct gbp_rule_t_ gbp_rule_t
unsigned long u64
Definition: types.h:89
struct gbp_contract_key_t_ gbp_contract_key_t
The key for an Contract.
The key for an Contract.
Definition: gbp_contract.h:48
#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:58
u32 thread_index
Definition: main.h:249
ip46_address_t gnh_ip
Definition: gbp_contract.h:68
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:41
u8 * format_gbp_rule_action(u8 *s, va_list *args)
Definition: gbp_contract.c:171
vlib_main_t * vm
Definition: in2out_ed.c:1582
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp_contract.h:158
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:217
gbp_policy_node_t_
Definition: gbp_contract.h:107
gbp_rule_action_t_
Definition: gbp_contract.h:95
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:402
unsigned char u8
Definition: types.h:56
#define static_always_inline
Definition: clib.h:108
vl_api_ip6_address_t ip6
Definition: one.api:424
vlib_combined_counter_main_t gbp_contract_drop_counters
Definition: gbp_contract.c:56
u16 gbp_scope_t
Definition: gbp_types.h:24
vlib_combined_counter_main_t gbp_contract_permit_counters
Definition: gbp_contract.c:51
struct gbp_contract_db_t_ gbp_contract_db_t
EPG src,dst pair to ACL mapping table, aka contract DB.
void gbp_contract_walk(gbp_contract_cb_t bgpe, void *ctx)
Definition: gbp_contract.c:565
unsigned int u32
Definition: types.h:88
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
Definition: vec.h:1012
gbp_contract_db_t gbp_contract_db
DP functions and databases.
Definition: gbp_contract.c:36
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)
uword * gc_hash
We can form a u64 key from the pair, so use a simple hash table.
Definition: gbp_contract.h:163
gbp_contract_apply_type_t
Definition: gbp_contract.h:225
vl_api_fib_path_type_t type
Definition: fib_types.api:123
gbp_hash_mode_t_
Definition: gbp_contract.h:83
int gbp_contract_delete(gbp_scope_t scope, sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:536
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
gbp_rule_t * gbp_rule_pool
Definition: gbp_contract.c:44
#define gm
Definition: dlmalloc.c:1219
#define foreach_gbp_policy_node
Definition: gbp_contract.h:102
long ctx[MAX_CONNS]
Definition: main.c:144
index_t * gc_rules
The ACL to apply for packets from the source to the destination EPG.
Definition: gbp_contract.h:147
unsigned short u16
Definition: types.h:57
sclass_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:58
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
u16 sclass
Definition: gbp.api:131
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
gbp_rule_action_t gu_action
Definition: gbp_contract.h:120
#define PREDICT_FALSE(x)
Definition: clib.h:120
#define always_inline
Definition: ipsec.h:28
#define GBP_POLICY_N_NODES
Definition: gbp_contract.h:113
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:313
An node in the FIB graph.
Definition: fib_node.h:295
gbp_contract_error_t
Definition: gbp_contract.h:34
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:650
enum gbp_hash_mode_t_ gbp_hash_mode_t
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_parse_match_function_t rule_match
Definition: parse.h:189
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
char * gbp_contract_error_strings[GBP_CONTRACT_N_ERROR]
Definition: gbp_contract.c:27
vl_api_gbp_rule_t rules[n_rules]
Definition: gbp.api:338
mac_address_t gnh_mac
Definition: gbp_contract.h:69
u32 stats_index
Definition: ip.api:143
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)
struct gbp_contract_t_ gbp_contract_t
A Group Based Policy Contract.
static gbp_contract_t * gbp_contract_get(index_t gci)
Definition: gbp_contract.h:209
index_t gbp_rule_alloc(gbp_rule_action_t action, gbp_hash_mode_t hash_mode, index_t *nhs)
Definition: gbp_contract.c:62
enum gbp_rule_action_t_ gbp_rule_action_t
typedef key
Definition: ipsec_types.api:85
#define foreach_gbp_contract_error
Definition: gbp_contract.h:22
vl_api_address_t ip
Definition: l2.api:501
vl_api_mac_event_action_t action
Definition: l2.api:181
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
acl_plugin_methods_t acl_plugin
Definition: gbp.h:45
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
gbp_scope_t gck_scope
Definition: gbp_contract.h:54
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
#define foreach_gbp_rule_action
Definition: gbp_contract.h:90
#define foreach_gbp_hash_mode
Definition: gbp_contract.h:78
A collection of combined counters.
Definition: counter.h:188
Group Base Policy (GBP) defines:
Definition: gbp.h:42
#define vnet_buffer(b)
Definition: buffer.h:417
enum gbp_policy_node_t_ gbp_policy_node_t
gbp_hash_mode_t gu_hash_mode
Definition: gbp_contract.h:121
u16 allowed_ethertypes[16]
Definition: gbp.api:336
u16 dclass
Definition: gbp.api:333
vl_api_gbp_scope_t scope
Definition: gbp.api:78
index_t * gu_nhs
Definition: gbp_contract.h:122
gbp_contract_t * gbp_contract_pool
Definition: gbp_contract.c:38
static index_t gbp_contract_find(gbp_contract_key_t *key)
Definition: gbp_contract.h:194
A Group Based Policy Contract.
Definition: gbp_contract.h:134
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:182