FD.io VPP  v19.08-27-gf4dcae4
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 
33 typedef enum
34 {
35 #define _(sym,str) GBP_CONTRACT_ERROR_##sym,
37 #undef _
39 #define GBP_CONTRACT_N_ERROR GBP_CONTRACT_N_ERROR
41 
43 
44 /**
45  * The key for an Contract
46  */
47 typedef struct gbp_contract_key_t_
48 {
49  union
50  {
51  struct
52  {
54  /**
55  * source and destination EPGs for which the ACL applies
56  */
59  };
61  };
63 
64 typedef struct gbp_next_hop_t_
65 {
67  ip46_address_t gnh_ip;
76 
77 #define foreach_gbp_hash_mode \
78  _(SRC_IP, "src-ip") \
79  _(DST_IP, "dst-ip") \
80  _(SYMMETRIC, "symmetric")
81 
82 typedef enum gbp_hash_mode_t_
83 {
84 #define _(v,s) GBP_HASH_MODE_##v,
86 #undef _
88 
89 #define foreach_gbp_rule_action \
90  _(PERMIT, "permit") \
91  _(DENY, "deny") \
92  _(REDIRECT, "redirect")
93 
94 typedef enum gbp_rule_action_t_
95 {
96 #define _(v,s) GBP_RULE_##v,
98 #undef _
100 
101 #define foreach_gbp_policy_node \
102  _(L2, "L2") \
103  _(IP4, "ip4") \
104  _(IP6, "ip6")
105 
106 typedef enum gbp_policy_node_t_
107 {
108 #define _(v,s) GBP_POLICY_NODE_##v,
110 #undef _
112 #define GBP_POLICY_N_NODES (GBP_POLICY_NODE_IP6+1)
113 
114 #define FOR_EACH_GBP_POLICY_NODE(pnode) \
115  for (pnode = GBP_POLICY_NODE_L2; pnode < GBP_POLICY_N_NODES; pnode++)
116 
117 typedef struct gbp_rule_t_
118 {
122 
123  /**
124  * DPO of the load-balance object used to redirect
125  */
127 } gbp_rule_t;
128 
129 /**
130  * A Group Based Policy Contract.
131  * Determines the ACL that applies to traffic pass between two endpoint groups
132  */
133 typedef struct gbp_contract_t_
134 {
135  /**
136  * source and destination EPGs
137  */
139 
142 
143  /**
144  * The ACL to apply for packets from the source to the destination EPG
145  */
147 
148  /**
149  * An ethertype whitelist
150  */
153 
154 /**
155  * EPG src,dst pair to ACL mapping table, aka contract DB
156  */
157 typedef struct gbp_contract_db_t_
158 {
159  /**
160  * We can form a u64 key from the pair, so use a simple hash table
161  */
164 
168  u32 acl_index,
169  index_t * rules,
170  u16 * allowed_ethertypes, u32 * stats_index);
172  sclass_t dclass);
173 
175  gbp_hash_mode_t hash_mode, index_t * nhs);
176 extern index_t gbp_next_hop_alloc (const ip46_address_t * ip,
177  index_t grd,
178  const mac_address_t * mac, index_t gbd);
179 
180 typedef int (*gbp_contract_cb_t) (gbp_contract_t * gbpe, void *ctx);
181 extern void gbp_contract_walk (gbp_contract_cb_t bgpe, void *ctx);
182 
183 extern u8 *format_gbp_contract (u8 * s, va_list * args);
184 
185 /**
186  * DP functions and databases
187  */
189 
192 {
193  uword *p;
194 
195  p = hash_get (gbp_contract_db.gc_hash, key->as_u64);
196 
197  if (NULL != p)
198  return (p[0]);
199 
200  return (INDEX_INVALID);
201 }
202 
204 
207 {
208  return (pool_elt_at_index (gbp_contract_pool, gci));
209 }
210 
211 extern gbp_rule_t *gbp_rule_pool;
212 
215 {
216  return (pool_elt_at_index (gbp_rule_pool, gui));
217 }
218 
221 
222 typedef enum
223 {
228 
232  gbp_rule_t ** rule, u32 * intra, u32 * sclass1,
233  gbp_contract_error_t * err,
235 {
236  fa_5tuple_opaque_t fa_5tuple;
237  const gbp_contract_t *contract;
238  index_t contract_index;
239  u32 acl_pos, acl_match, rule_match, trace_bitmap;
240  u16 etype;
241  u8 ip6, action;
242 
243  *rule = 0;
244 
245  if (key->gck_src == key->gck_dst)
246  {
247  /* intra-epg allowed */
248  (*intra)++;
249  *err = GBP_CONTRACT_ERROR_ALLOW_INTRA;
250  return GBP_RULE_PERMIT;
251  }
252 
253  if (1 == key->gck_src || 1 == key->gck_dst)
254  {
255  /* sclass 1 allowed */
256  (*sclass1)++;
257  *err = GBP_CONTRACT_ERROR_ALLOW_SCLASS_1;
258  return GBP_RULE_PERMIT;
259  }
260 
261  /* look for contract */
262  contract_index = gbp_contract_find (key);
263  if (INDEX_INVALID == contract_index)
264  {
265  *err = GBP_CONTRACT_ERROR_DROP_NO_CONTRACT;
266  return GBP_RULE_DENY;
267  }
268 
269  contract = gbp_contract_get (contract_index);
270 
271  *err = GBP_CONTRACT_ERROR_DROP_CONTRACT;
272 
273  switch (type)
274  {
276  ip6 = 0;
277  break;
279  ip6 = 1;
280  break;
282  {
283  /* check ethertype */
284  etype =
285  ((u16 *) (vlib_buffer_get_current (b) +
286  vnet_buffer (b)->l2.l2_len))[-1];
287 
288  if (~0 == vec_search (contract->gc_allowed_ethertypes, etype))
289  {
290  *err = GBP_CONTRACT_ERROR_DROP_ETHER_TYPE;
291  goto contract_deny;
292  }
293 
294  switch (clib_net_to_host_u16 (etype))
295  {
296  case ETHERNET_TYPE_IP4:
297  ip6 = 0;
298  break;
299  case ETHERNET_TYPE_IP6:
300  ip6 = 1;
301  break;
302  default:
303  goto contract_deny;
304  }
305  }
306  break;
307  }
308 
309  /* check ACL */
310  action = 0;
312  contract->gc_lc_index, b, ip6,
313  GBP_CONTRACT_APPLY_L2 != type /* input */ ,
314  GBP_CONTRACT_APPLY_L2 == type /* l2_path */ ,
315  &fa_5tuple);
317  contract->gc_lc_index, &fa_5tuple, ip6,
318  &action, &acl_pos, &acl_match, &rule_match,
319  &trace_bitmap);
320  if (action <= 0)
321  goto contract_deny;
322 
323  *rule = gbp_rule_get (contract->gc_rules[rule_match]);
324  switch ((*rule)->gu_action)
325  {
326  case GBP_RULE_PERMIT:
327  case GBP_RULE_REDIRECT:
328  *err = GBP_CONTRACT_ERROR_ALLOW_CONTRACT;
329  vlib_increment_combined_counter (&gbp_contract_permit_counters,
330  vm->thread_index, contract_index, 1,
332  return (*rule)->gu_action;
333  case GBP_RULE_DENY:
334  break;
335  }
336 
337 contract_deny:
338  vlib_increment_combined_counter (&gbp_contract_drop_counters,
339  vm->thread_index, contract_index, 1,
341  return GBP_RULE_DENY;
342 }
343 
344 #endif /* __GBP_CONTRACT_H__ */
345 /*
346  * fd.io coding-style-patch-verification: ON
347  *
348  * Local Variables:
349  * eval: (c-set-style "gnu")
350  * End:
351  */
u16 * gc_allowed_ethertypes
An ethertype whitelist.
Definition: gbp_contract.h:151
u32 acl_index
Definition: gbp.api:310
#define GBP_CONTRACT_N_ERROR
Definition: gbp_contract.h:39
u16 sclass_t
Definition: gbp_types.h:25
gbp_contract_key_t gc_key
source and destination EPGs
Definition: gbp_contract.h:138
vl_api_mac_address_t mac
Definition: l2.api:490
fib_node_t gnh_node
Definition: gbp_contract.h:66
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.
#define NULL
Definition: clib.h:58
The key for an Contract.
Definition: gbp_contract.h:47
#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:197
ip46_address_t gnh_ip
Definition: gbp_contract.h:67
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
EPG src,dst pair to ACL mapping table, aka contract DB.
Definition: gbp_contract.h:157
static gbp_rule_t * gbp_rule_get(index_t gui)
Definition: gbp_contract.h:214
gbp_policy_node_t_
Definition: gbp_contract.h:106
gbp_rule_action_t_
Definition: gbp_contract.h:94
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:366
unsigned char u8
Definition: types.h:56
#define static_always_inline
Definition: clib.h:99
#define always_inline
Definition: clib.h:98
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:557
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:940
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:162
gbp_contract_apply_type_t
Definition: gbp_contract.h:222
vl_api_fib_path_type_t type
Definition: fib_types.api:123
gbp_hash_mode_t_
Definition: gbp_contract.h:82
int gbp_contract_delete(gbp_scope_t scope, sclass_t sclass, sclass_t dclass)
Definition: gbp_contract.c:528
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:514
gbp_rule_t * gbp_rule_pool
Definition: gbp_contract.c:44
#define gm
Definition: dlmalloc.c:1217
#define foreach_gbp_policy_node
Definition: gbp_contract.h:101
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:146
unsigned short u16
Definition: types.h:57
sclass_t gck_src
source and destination EPGs for which the ACL applies
Definition: gbp_contract.h:57
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:122
gbp_rule_action_t gu_action
Definition: gbp_contract.h:119
#define GBP_POLICY_N_NODES
Definition: gbp_contract.h:112
vl_api_gbp_next_hop_t nhs[8]
Definition: gbp.api:289
An node in the FIB graph.
Definition: fib_node.h:295
gbp_contract_error_t
Definition: gbp_contract.h:33
u8 * format_gbp_contract(u8 *s, va_list *args)
Definition: gbp_contract.c:642
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, gbp_contract_error_t *err, gbp_contract_apply_type_t type)
Definition: gbp_contract.h:230
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:77
vlib_main_t * vm
Definition: buffer.c:312
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:457
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:314
mac_address_t gnh_mac
Definition: gbp_contract.h:68
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:206
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
#define foreach_gbp_contract_error
Definition: gbp_contract.h:22
vl_api_address_t ip
Definition: l2.api:489
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:53
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
#define foreach_gbp_rule_action
Definition: gbp_contract.h:89
typedef key
Definition: ipsec.api:245
#define foreach_gbp_hash_mode
Definition: gbp_contract.h:77
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:361
enum gbp_policy_node_t_ gbp_policy_node_t
gbp_hash_mode_t gu_hash_mode
Definition: gbp_contract.h:120
u16 allowed_ethertypes[16]
Definition: gbp.api:312
u16 dclass
Definition: gbp.api:309
vl_api_gbp_scope_t scope
Definition: gbp.api:73
index_t * gu_nhs
Definition: gbp_contract.h:121
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:191
A Group Based Policy Contract.
Definition: gbp_contract.h:133
int(* gbp_contract_cb_t)(gbp_contract_t *gbpe, void *ctx)
Definition: gbp_contract.h:180