FD.io VPP  v17.07.01-10-g3be13f0
Vector Packet Processing
lisp_gpe_tenant.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 
17 
18 /**
19  * The pool of all tenants
20  */
22 
23 /**
24  * The hash table of all tenants: key:{VNI}.
25  */
27 
28 static lisp_gpe_tenant_t *
30 {
31  uword *p;
32 
33  p = hash_get (lisp_gpe_tenant_db, vni);
34 
35  if (NULL == p)
36  return (NULL);
37 
38  return (pool_elt_at_index (lisp_gpe_tenant_pool, p[0]));
39 }
40 
41 static lisp_gpe_tenant_t *
43 {
45 
46  lt = lisp_gpe_tenant_find (vni);
47 
48  if (NULL == lt)
49  {
50  pool_get (lisp_gpe_tenant_pool, lt);
51  memset (lt, 0, sizeof (*lt));
52 
53  lt->lt_vni = vni;
54  lt->lt_table_id = ~0;
55  lt->lt_bd_id = ~0;
56 
57  hash_set (lisp_gpe_tenant_db, vni, lt - lisp_gpe_tenant_pool);
58  }
59 
60  return (lt);
61 }
62 
63 /**
64  * @brief Find or create a tenant for the given VNI
65  */
66 u32
68 {
70 
71  lt = lisp_gpe_tenant_find (vni);
72 
73  if (NULL == lt)
74  {
76  }
77 
78  return (lt - lisp_gpe_tenant_pool);
79 }
80 
81 /**
82  * @brief If there are no more locks/users of te tenant, then delete it
83  */
84 static void
86 {
87  int i;
88 
89  for (i = 0; i < LISP_GPE_TENANT_LOCK_NUM; i++)
90  {
91  if (lt->lt_locks[i])
92  return;
93  }
94 
96  pool_put (lisp_gpe_tenant_pool, lt);
97 }
98 
99 /**
100  * @brief Add/create and lock a new or find and lock the existing L3
101  * interface for the tenant
102  *
103  * @paran vni The tenant's VNI
104  * @param table_id the Tenant's L3 table ID.
105  *
106  * @return the SW IF index of the L3 interface
107  */
108 u32
110 {
111  lisp_gpe_tenant_t *lt;
112 
114 
115  if (~0 == lt->lt_table_id)
116  lt->lt_table_id = table_id;
117 
118  ASSERT (lt->lt_table_id == table_id);
119 
121  {
122  /* create the l3 interface since there are currently no users of it */
123  lt->lt_l3_sw_if_index =
124  lisp_gpe_add_l3_iface (&lisp_gpe_main, vni, table_id);
125  }
126 
128 
129  return (lt->lt_l3_sw_if_index);
130 }
131 
132 /**
133  * @brief Release the lock held on the tenant's L3 interface
134  */
135 void
137 {
138  lisp_gpe_tenant_t *lt;
139 
140  lt = lisp_gpe_tenant_find (vni);
141 
142  if (NULL == lt)
143  {
144  clib_warning ("No tenant for VNI %d", vni);
145  return;
146  }
147 
149  {
150  clib_warning ("No L3 interface for tenant VNI %d", vni);
151  return;
152  }
153 
155 
157  {
158  /* the last user has gone, so delete the l3 interface */
160  }
161 
162  /*
163  * If there are no more locks on any tenant managed resource, then
164  * this tenant is toast.
165  */
167 }
168 
169 /**
170  * @brief Add/create and lock a new or find and lock the existing L2
171  * interface for the tenant
172  *
173  * @paran vni The tenant's VNI
174  * @param table_id the Tenant's L2 Bridge Domain ID.
175  *
176  * @return the SW IF index of the L2 interface
177  */
178 u32
180 {
181  lisp_gpe_tenant_t *lt;
182 
184 
185  if (NULL == lt)
186  {
187  clib_warning ("No tenant for VNI %d", vni);
188  return ~0;
189  }
190 
191  if (~0 == lt->lt_bd_id)
192  lt->lt_bd_id = bd_id;
193 
194  ASSERT (lt->lt_bd_id == bd_id);
195 
197  {
198  /* create the l2 interface since there are currently no users of it */
199  lt->lt_l2_sw_if_index =
200  lisp_gpe_add_l2_iface (&lisp_gpe_main, vni, bd_id);
201  }
202 
204 
205  return (lt->lt_l2_sw_if_index);
206 }
207 
208 /**
209  * @brief Release the lock held on the tenant's L3 interface
210  */
211 void
213 {
214  lisp_gpe_tenant_t *lt;
215 
216  lt = lisp_gpe_tenant_find (vni);
217 
218  if (NULL == lt)
219  {
220  clib_warning ("No tenant for VNI %d", vni);
221  return;
222  }
223 
225  {
226  clib_warning ("No L2 interface for tenant VNI %d", vni);
227  return;
228  }
229 
231 
233  {
234  /* the last user has gone, so delete the l2 interface */
236  }
237 
238  /*
239  * If there are no more locks on any tenant managed resource, then
240  * this tenant is toast.
241  */
243 }
244 
245 /**
246  * @brief get a const pointer to the tenant object
247  */
248 const lisp_gpe_tenant_t *
250 {
251  return (pool_elt_at_index (lisp_gpe_tenant_pool, index));
252 }
253 
254 /**
255  * @brief Flush/delete ALL the tenants
256  */
257 void
259 {
260  lisp_gpe_tenant_t *lt;
261 
262  /* *INDENT-OFF* */
263  pool_foreach(lt, lisp_gpe_tenant_pool,
264  ({
267  }));
268  /* *INDENT-ON* */
269 }
270 
271 /**
272  * @brif Show/display one tenant
273  */
274 static u8 *
275 format_lisp_gpe_tenant (u8 * s, va_list ap)
276 {
277  const lisp_gpe_tenant_t *lt = va_arg (ap, lisp_gpe_tenant_t *);
278 
279  s = format (s, "VNI:%d ", lt->lt_vni);
280 
281  if (lt->lt_table_id != ~0)
282  {
283  s = format (s, "VRF:%d ", lt->lt_table_id);
284  s = format (s, "L3-SW-IF:%d ", lt->lt_l3_sw_if_index);
285  }
286 
287  if (lt->lt_bd_id != ~0)
288  {
289  s = format (s, "BD-ID:%d ", lt->lt_bd_id);
290  s = format (s, "L2-SW-IF:%d ", lt->lt_l2_sw_if_index);
291  }
292 
293  return (s);
294 }
295 
296 /**
297  * @brief CLI command to show LISP-GPE tenant.
298  */
299 static clib_error_t *
301  unformat_input_t * input, vlib_cli_command_t * cmd)
302 {
303  lisp_gpe_tenant_t *lt;
304 
305  /* *INDENT-OFF* */
306  pool_foreach (lt, lisp_gpe_tenant_pool,
307  ({
308  vlib_cli_output (vm, "%U", format_lisp_gpe_tenant, lt);
309  }));
310  /* *INDENT-ON* */
311 
312  return 0;
313 }
314 
315 /* *INDENT-OFF* */
316 VLIB_CLI_COMMAND (lisp_gpe_tenant_command) = {
317  .path = "show gpe tenant",
318  .short_help = "show gpe tenant",
319  .function = lisp_gpe_tenant_show,
320 };
321 /* *INDENT-ON* */
322 
323 
324 /*
325  * fd.io coding-style-patch-verification: ON
326  *
327  * Local Variables:
328  * eval: (c-set-style "gnu")
329  * End:
330  */
void lisp_gpe_tenant_l2_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
#define hash_unset(h, key)
Definition: hash.h:260
u32 lisp_gpe_add_l2_iface(lisp_gpe_main_t *lgm, u32 vni, u32 bd_id)
Add/del LISP-GPE L2 interface.
Definition: interface.c:648
u32 lt_table_id
The tenant can have both L2 and L3 services enabled.
void lisp_gpe_tenant_l3_iface_unlock(u32 vni)
Release the lock held on the tenant&#39;s L3 interface.
#define NULL
Definition: clib.h:55
static void lisp_gpe_tenant_delete_if_empty(lisp_gpe_tenant_t *lt)
If there are no more locks/users of te tenant, then delete it.
LISP-GPE global state.
Definition: lisp_gpe.h:118
static lisp_gpe_tenant_t * lisp_gpe_tenant_pool
The pool of all tenants.
uword * lisp_gpe_tenant_db
The hash table of all tenants: key:{VNI}.
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u32 lisp_gpe_tenant_find_or_create(u32 vni)
Find or create a tenant for the given VNI.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
void lisp_gpe_del_l3_iface(lisp_gpe_main_t *lgm, u32 vni, u32 table_id)
Definition: interface.c:611
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
static clib_error_t * lisp_gpe_tenant_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to show LISP-GPE tenant.
u32 lisp_gpe_tenant_l2_iface_add_or_lock(u32 vni, u32 bd_id)
Add/create and lock a new or find and lock the existing L2 interface for the tenant.
static lisp_gpe_tenant_t * lisp_gpe_tenant_find(u32 vni)
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
u32 lt_l3_sw_if_index
The L3 SW interface index.
const lisp_gpe_tenant_t * lisp_gpe_tenant_get(u32 index)
get a const pointer to the tenant object
static u8 * format_lisp_gpe_tenant(u8 *s, va_list ap)
Show/display one tenant
void lisp_gpe_tenant_flush(void)
Flush/delete ALL the tenants.
u32 lt_vni
The VNI is the identifier of the tenant.
#define clib_warning(format, args...)
Definition: error.h:59
void lisp_gpe_del_l2_iface(lisp_gpe_main_t *lgm, u32 vni, u32 bd_id)
Add/del LISP-GPE L2 interface.
Definition: interface.c:711
static lisp_gpe_tenant_t * lisp_gpe_tenant_find_or_create_i(u32 vni)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u64 uword
Definition: types.h:112
u32 lt_l2_sw_if_index
The L2 SW interface index.
unsigned char u8
Definition: types.h:56
u32 lt_locks[LISP_GPE_TENANT_LOCK_NUM]
The number of locks on the tenant&#39;s L3 interface.
Representation of the data associated with a LISP overlay tenant.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
u32 lisp_gpe_tenant_l3_iface_add_or_lock(u32 vni, u32 table_id)
Add/create and lock a new or find and lock the existing L3 interface for the tenant.
u32 lisp_gpe_add_l3_iface(lisp_gpe_main_t *lgm, u32 vni, u32 table_id)
Add/del LISP-GPE L3 interface.
Definition: interface.c:571