FD.io VPP  v18.10-34-gcce845e
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  * @param with_default_route Install default route for the interface
106  *
107  * @return the SW IF index of the L3 interface
108  */
109 u32
111  u8 with_default_route)
112 {
113  lisp_gpe_tenant_t *lt;
114 
116 
117  if (~0 == lt->lt_table_id)
118  lt->lt_table_id = table_id;
119 
120  ASSERT (lt->lt_table_id == table_id);
121 
123  {
124  /* create the l3 interface since there are currently no users of it */
125  lt->lt_l3_sw_if_index =
126  lisp_gpe_add_l3_iface (&lisp_gpe_main, vni, table_id,
127  with_default_route);
128  }
129 
131 
132  return (lt->lt_l3_sw_if_index);
133 }
134 
135 /**
136  * @brief Release the lock held on the tenant's L3 interface
137  */
138 void
140 {
141  lisp_gpe_tenant_t *lt;
142 
143  lt = lisp_gpe_tenant_find (vni);
144 
145  if (NULL == lt)
146  {
147  clib_warning ("No tenant for VNI %d", vni);
148  return;
149  }
150 
152  {
153  clib_warning ("No L3 interface for tenant VNI %d", vni);
154  return;
155  }
156 
158 
160  {
161  /* the last user has gone, so delete the l3 interface */
163  }
164 
165  /*
166  * If there are no more locks on any tenant managed resource, then
167  * this tenant is toast.
168  */
170 }
171 
172 /**
173  * @brief Add/create and lock a new or find and lock the existing L2
174  * interface for the tenant
175  *
176  * @paran vni The tenant's VNI
177  * @param table_id the Tenant's L2 Bridge Domain ID.
178  *
179  * @return the SW IF index of the L2 interface
180  */
181 u32
183 {
184  lisp_gpe_tenant_t *lt;
185 
187 
188  if (NULL == lt)
189  {
190  clib_warning ("No tenant for VNI %d", vni);
191  return ~0;
192  }
193 
194  if (~0 == lt->lt_bd_id)
195  lt->lt_bd_id = bd_id;
196 
197  ASSERT (lt->lt_bd_id == bd_id);
198 
200  {
201  /* create the l2 interface since there are currently no users of it */
202  lt->lt_l2_sw_if_index =
203  lisp_gpe_add_l2_iface (&lisp_gpe_main, vni, bd_id);
204  }
205 
207 
208  return (lt->lt_l2_sw_if_index);
209 }
210 
211 /**
212  * @brief Release the lock held on the tenant's L3 interface
213  */
214 void
216 {
217  lisp_gpe_tenant_t *lt;
218 
219  lt = lisp_gpe_tenant_find (vni);
220 
221  if (NULL == lt)
222  {
223  clib_warning ("No tenant for VNI %d", vni);
224  return;
225  }
226 
228  {
229  clib_warning ("No L2 interface for tenant VNI %d", vni);
230  return;
231  }
232 
234 
236  {
237  /* the last user has gone, so delete the l2 interface */
239  }
240 
241  /*
242  * If there are no more locks on any tenant managed resource, then
243  * this tenant is toast.
244  */
246 }
247 
248 /**
249  * @brief get a const pointer to the tenant object
250  */
251 const lisp_gpe_tenant_t *
253 {
254  return (pool_elt_at_index (lisp_gpe_tenant_pool, index));
255 }
256 
257 /**
258  * @brief Flush/delete ALL the tenants
259  */
260 void
262 {
263  lisp_gpe_tenant_t *lt;
264 
265  /* *INDENT-OFF* */
266  pool_foreach(lt, lisp_gpe_tenant_pool,
267  ({
270  }));
271  /* *INDENT-ON* */
272 }
273 
274 /**
275  * @brif Show/display one tenant
276  */
277 static u8 *
278 format_lisp_gpe_tenant (u8 * s, va_list * ap)
279 {
280  const lisp_gpe_tenant_t *lt = va_arg (*ap, lisp_gpe_tenant_t *);
281 
282  s = format (s, "VNI:%d ", lt->lt_vni);
283 
284  if (lt->lt_table_id != ~0)
285  {
286  s = format (s, "VRF:%d ", lt->lt_table_id);
287  s = format (s, "L3-SW-IF:%d ", lt->lt_l3_sw_if_index);
288  }
289 
290  if (lt->lt_bd_id != ~0)
291  {
292  s = format (s, "BD-ID:%d ", lt->lt_bd_id);
293  s = format (s, "L2-SW-IF:%d ", lt->lt_l2_sw_if_index);
294  }
295 
296  return (s);
297 }
298 
299 /**
300  * @brief CLI command to show LISP-GPE tenant.
301  */
302 static clib_error_t *
304  unformat_input_t * input, vlib_cli_command_t * cmd)
305 {
306  lisp_gpe_tenant_t *lt;
307 
308  /* *INDENT-OFF* */
309  pool_foreach (lt, lisp_gpe_tenant_pool,
310  ({
311  vlib_cli_output (vm, "%U", format_lisp_gpe_tenant, lt);
312  }));
313  /* *INDENT-ON* */
314 
315  return 0;
316 }
317 
318 /* *INDENT-OFF* */
319 VLIB_CLI_COMMAND (lisp_gpe_tenant_command) = {
320  .path = "show gpe tenant",
321  .short_help = "show gpe tenant",
322  .function = lisp_gpe_tenant_show,
323 };
324 /* *INDENT-ON* */
325 
326 
327 /*
328  * fd.io coding-style-patch-verification: ON
329  *
330  * Local Variables:
331  * eval: (c-set-style "gnu")
332  * End:
333  */
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:255
#define hash_unset(h, key)
Definition: hash.h:261
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:657
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:57
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
int i
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:228
unsigned char u8
Definition: types.h:56
void lisp_gpe_del_l3_iface(lisp_gpe_main_t *lgm, u32 vni, u32 table_id)
Definition: interface.c:620
memset(h->entries, 0, sizeof(h->entries[0])*entries)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
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_add_l3_iface(lisp_gpe_main_t *lgm, u32 vni, u32 table_id, u8 with_default_routes)
Add/del LISP-GPE L3 interface.
Definition: interface.c:578
unsigned int u32
Definition: types.h:88
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:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
u32 lisp_gpe_tenant_l3_iface_add_or_lock(u32 vni, u32 table_id, u8 with_default_route)
Add/create and lock a new or find and lock the existing L3 interface for the tenant.
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
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
vlib_main_t * vm
Definition: buffer.c:294
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:720
static lisp_gpe_tenant_t * lisp_gpe_tenant_find_or_create_i(u32 vni)
static u8 * format_lisp_gpe_tenant(u8 *s, va_list *ap)
Show/display one tenant
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define ASSERT(truth)
u32 lt_l2_sw_if_index
The L2 SW interface index.
u64 uword
Definition: types.h:112
u32 vni
Definition: vxlan_gbp.api:38
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:725