blob: 683026e5c069dcc7ee983593f5edaa6fc6b1b428 [file] [log] [blame]
Feng Lu41f44a22015-05-22 11:39:56 +02001/*
2 * VRF functions.
3 * Copyright (C) 2014 6WIND S.A.
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
Feng Lu126215c2015-05-22 11:39:58 +020025#include "if.h"
Feng Lu41f44a22015-05-22 11:39:56 +020026#include "vrf.h"
27#include "prefix.h"
28#include "table.h"
29#include "log.h"
30#include "memory.h"
31
Feng Lufb2bfc12015-05-22 11:40:08 +020032#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
33
Feng Lu41f44a22015-05-22 11:39:56 +020034struct vrf
35{
36 /* Identifier, same as the vector index */
37 vrf_id_t vrf_id;
38 /* Name */
39 char *name;
40
Feng Lu5a5702f2015-05-22 11:39:59 +020041 /* Master list of interfaces belonging to this VRF */
42 struct list *iflist;
43
Feng Lu41f44a22015-05-22 11:39:56 +020044 /* User data */
45 void *info;
46};
47
48/* Holding VRF hooks */
49struct vrf_master
50{
51 int (*vrf_new_hook) (vrf_id_t, void **);
52 int (*vrf_delete_hook) (vrf_id_t, void **);
Feng Lufb2bfc12015-05-22 11:40:08 +020053 int (*vrf_enable_hook) (vrf_id_t, void **);
54 int (*vrf_disable_hook) (vrf_id_t, void **);
Feng Lu41f44a22015-05-22 11:39:56 +020055} vrf_master = {0,};
56
57/* VRF table */
58struct route_table *vrf_table = NULL;
59
Feng Lufb2bfc12015-05-22 11:40:08 +020060static int vrf_is_enabled (struct vrf *vrf);
61static int vrf_enable (struct vrf *vrf);
62static void vrf_disable (struct vrf *vrf);
63
64
Feng Lu41f44a22015-05-22 11:39:56 +020065/* Build the table key */
66static void
67vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
68{
69 p->family = AF_INET;
70 p->prefixlen = IPV4_MAX_BITLEN;
71 p->u.prefix4.s_addr = vrf_id;
72}
73
74/* Get a VRF. If not found, create one. */
75static struct vrf *
76vrf_get (vrf_id_t vrf_id)
77{
78 struct prefix p;
79 struct route_node *rn;
80 struct vrf *vrf;
81
82 vrf_build_key (vrf_id, &p);
83 rn = route_node_get (vrf_table, &p);
84 if (rn->info)
85 {
86 vrf = (struct vrf *)rn->info;
87 route_unlock_node (rn); /* get */
88 return vrf;
89 }
90
91 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
92 vrf->vrf_id = vrf_id;
93 rn->info = vrf;
94
Feng Lu5a5702f2015-05-22 11:39:59 +020095 /* Initialize interfaces. */
96 if_init (vrf_id, &vrf->iflist);
97
Feng Lu41f44a22015-05-22 11:39:56 +020098 zlog_info ("VRF %u is created.", vrf_id);
99
100 if (vrf_master.vrf_new_hook)
101 (*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
102
103 return vrf;
104}
105
106/* Delete a VRF. This is called in vrf_terminate(). */
107static void
108vrf_delete (struct vrf *vrf)
109{
110 zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
111
Feng Lufb2bfc12015-05-22 11:40:08 +0200112 if (vrf_is_enabled (vrf))
113 vrf_disable (vrf);
114
Feng Lu41f44a22015-05-22 11:39:56 +0200115 if (vrf_master.vrf_delete_hook)
116 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
117
Feng Lu5a5702f2015-05-22 11:39:59 +0200118 if_terminate (vrf->vrf_id, &vrf->iflist);
119
Feng Lu41f44a22015-05-22 11:39:56 +0200120 if (vrf->name)
121 XFREE (MTYPE_VRF_NAME, vrf->name);
122
123 XFREE (MTYPE_VRF, vrf);
124}
125
126/* Look up a VRF by identifier. */
127static struct vrf *
128vrf_lookup (vrf_id_t vrf_id)
129{
130 struct prefix p;
131 struct route_node *rn;
132 struct vrf *vrf = NULL;
133
134 vrf_build_key (vrf_id, &p);
135 rn = route_node_lookup (vrf_table, &p);
136 if (rn)
137 {
138 vrf = (struct vrf *)rn->info;
139 route_unlock_node (rn); /* lookup */
140 }
141 return vrf;
142}
143
Feng Lufb2bfc12015-05-22 11:40:08 +0200144/*
145 * Check whether the VRF is enabled - that is, whether the VRF
146 * is ready to allocate resources. Currently there's only one
147 * type of resource: socket.
148 */
149static int
150vrf_is_enabled (struct vrf *vrf)
151{
152 return vrf && vrf->vrf_id == VRF_DEFAULT;
153}
154
155/*
156 * Enable a VRF - that is, let the VRF be ready to use.
157 * The VRF_ENABLE_HOOK callback will be called to inform
158 * that they can allocate resources in this VRF.
159 *
160 * RETURN: 1 - enabled successfully; otherwise, 0.
161 */
162static int
163vrf_enable (struct vrf *vrf)
164{
165 /* Till now, only the default VRF can be enabled. */
166 if (vrf->vrf_id == VRF_DEFAULT)
167 {
168 zlog_info ("VRF %u is enabled.", vrf->vrf_id);
169
170 if (vrf_master.vrf_enable_hook)
171 (*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
172
173 return 1;
174 }
175
176 return 0;
177}
178
179/*
180 * Disable a VRF - that is, let the VRF be unusable.
181 * The VRF_DELETE_HOOK callback will be called to inform
182 * that they must release the resources in the VRF.
183 */
184static void
185vrf_disable (struct vrf *vrf)
186{
187 if (vrf_is_enabled (vrf))
188 {
189 zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
190
191 /* Till now, nothing to be done for the default VRF. */
192
193 if (vrf_master.vrf_disable_hook)
194 (*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
195 }
196}
197
198
Feng Lu41f44a22015-05-22 11:39:56 +0200199/* Add a VRF hook. Please add hooks before calling vrf_init(). */
200void
201vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
202{
203 switch (type) {
204 case VRF_NEW_HOOK:
205 vrf_master.vrf_new_hook = func;
206 break;
207 case VRF_DELETE_HOOK:
208 vrf_master.vrf_delete_hook = func;
209 break;
Feng Lufb2bfc12015-05-22 11:40:08 +0200210 case VRF_ENABLE_HOOK:
211 vrf_master.vrf_enable_hook = func;
212 break;
213 case VRF_DISABLE_HOOK:
214 vrf_master.vrf_disable_hook = func;
215 break;
Feng Lu41f44a22015-05-22 11:39:56 +0200216 default:
217 break;
218 }
219}
220
221/* Return the iterator of the first VRF. */
222vrf_iter_t
223vrf_first (void)
224{
225 struct route_node *rn;
226
227 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
228 if (rn->info)
229 {
230 route_unlock_node (rn); /* top/next */
231 return (vrf_iter_t)rn;
232 }
233 return VRF_ITER_INVALID;
234}
235
236/* Return the next VRF iterator to the given iterator. */
237vrf_iter_t
238vrf_next (vrf_iter_t iter)
239{
240 struct route_node *rn = NULL;
241
242 /* Lock it first because route_next() will unlock it. */
243 if (iter != VRF_ITER_INVALID)
244 rn = route_next (route_lock_node ((struct route_node *)iter));
245
246 for (; rn; rn = route_next (rn))
247 if (rn->info)
248 {
249 route_unlock_node (rn); /* next */
250 return (vrf_iter_t)rn;
251 }
252 return VRF_ITER_INVALID;
253}
254
255/* Return the VRF iterator of the given VRF ID. If it does not exist,
256 * the iterator of the next existing VRF is returned. */
257vrf_iter_t
258vrf_iterator (vrf_id_t vrf_id)
259{
260 struct prefix p;
261 struct route_node *rn;
262
263 vrf_build_key (vrf_id, &p);
264 rn = route_node_get (vrf_table, &p);
265 if (rn->info)
266 {
267 /* OK, the VRF exists. */
268 route_unlock_node (rn); /* get */
269 return (vrf_iter_t)rn;
270 }
271
272 /* Find the next VRF. */
273 for (rn = route_next (rn); rn; rn = route_next (rn))
274 if (rn->info)
275 {
276 route_unlock_node (rn); /* next */
277 return (vrf_iter_t)rn;
278 }
279
280 return VRF_ITER_INVALID;
281}
282
283/* Obtain the VRF ID from the given VRF iterator. */
284vrf_id_t
285vrf_iter2id (vrf_iter_t iter)
286{
287 struct route_node *rn = (struct route_node *) iter;
288 return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
289}
290
291/* Obtain the data pointer from the given VRF iterator. */
292void *
293vrf_iter2info (vrf_iter_t iter)
294{
295 struct route_node *rn = (struct route_node *) iter;
296 return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
297}
298
Feng Lu5a5702f2015-05-22 11:39:59 +0200299/* Obtain the interface list from the given VRF iterator. */
300struct list *
301vrf_iter2iflist (vrf_iter_t iter)
302{
303 struct route_node *rn = (struct route_node *) iter;
304 return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
305}
306
Feng Lu41f44a22015-05-22 11:39:56 +0200307/* Get the data pointer of the specified VRF. If not found, create one. */
308void *
309vrf_info_get (vrf_id_t vrf_id)
310{
311 struct vrf *vrf = vrf_get (vrf_id);
312 return vrf->info;
313}
314
315/* Look up the data pointer of the specified VRF. */
316void *
317vrf_info_lookup (vrf_id_t vrf_id)
318{
319 struct vrf *vrf = vrf_lookup (vrf_id);
320 return vrf ? vrf->info : NULL;
321}
322
Feng Lu5a5702f2015-05-22 11:39:59 +0200323/* Look up the interface list in a VRF. */
324struct list *
325vrf_iflist (vrf_id_t vrf_id)
326{
327 struct vrf * vrf = vrf_lookup (vrf_id);
328 return vrf ? vrf->iflist : NULL;
329}
330
331/* Get the interface list of the specified VRF. Create one if not find. */
332struct list *
333vrf_iflist_get (vrf_id_t vrf_id)
334{
335 struct vrf * vrf = vrf_get (vrf_id);
336 return vrf->iflist;
337}
338
Feng Luc99f3482014-10-16 09:52:36 +0800339/*
340 * VRF bit-map
341 */
342
343#define VRF_BITMAP_NUM_OF_GROUPS 8
344#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
345 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
346#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
347 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
348
349#define VRF_BITMAP_GROUP(_id) \
350 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
351#define VRF_BITMAP_BIT_OFFSET(_id) \
352 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
353
354#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
355 ((_bit_offset) / CHAR_BIT)
356#define VRF_BITMAP_FLAG(_bit_offset) \
357 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
358
359struct vrf_bitmap
360{
361 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
362};
363
364vrf_bitmap_t
365vrf_bitmap_init (void)
366{
367 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
368}
369
370void
371vrf_bitmap_free (vrf_bitmap_t bmap)
372{
373 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
374 int i;
375
376 if (bmap == VRF_BITMAP_NULL)
377 return;
378
379 for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
380 if (bm->groups[i])
381 XFREE (MTYPE_VRF_BITMAP, bm->groups[i]);
382
383 XFREE (MTYPE_VRF_BITMAP, bm);
384}
385
386void
387vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
388{
389 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
390 u_char group = VRF_BITMAP_GROUP (vrf_id);
391 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
392
393 if (bmap == VRF_BITMAP_NULL)
394 return;
395
396 if (bm->groups[group] == NULL)
397 bm->groups[group] = XCALLOC (MTYPE_VRF_BITMAP,
398 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
399
400 SET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
401 VRF_BITMAP_FLAG (offset));
402}
403
404void
405vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
406{
407 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
408 u_char group = VRF_BITMAP_GROUP (vrf_id);
409 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
410
411 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
412 return;
413
414 UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
415 VRF_BITMAP_FLAG (offset));
416}
417
418int
419vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
420{
421 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
422 u_char group = VRF_BITMAP_GROUP (vrf_id);
423 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
424
425 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
426 return 0;
427
428 return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
429 VRF_BITMAP_FLAG (offset)) ? 1 : 0;
430}
431
Feng Lu41f44a22015-05-22 11:39:56 +0200432/* Initialize VRF module. */
433void
434vrf_init (void)
435{
436 struct vrf *default_vrf;
437
438 /* Allocate VRF table. */
439 vrf_table = route_table_init ();
440
441 /* The default VRF always exists. */
442 default_vrf = vrf_get (VRF_DEFAULT);
443 if (!default_vrf)
444 {
445 zlog_err ("vrf_init: failed to create the default VRF!");
446 exit (1);
447 }
448
449 /* Set the default VRF name. */
Feng Lufb2bfc12015-05-22 11:40:08 +0200450 default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, VRF_DEFAULT_NAME);
451
452 /* Enable the default VRF. */
453 if (!vrf_enable (default_vrf))
454 {
455 zlog_err ("vrf_init: failed to enable the default VRF!");
456 exit (1);
457 }
Feng Lu41f44a22015-05-22 11:39:56 +0200458}
459
460/* Terminate VRF module. */
461void
462vrf_terminate (void)
463{
464 struct route_node *rn;
465 struct vrf *vrf;
466
467 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
468 if ((vrf = rn->info) != NULL)
469 vrf_delete (vrf);
470
471 route_table_finish (vrf_table);
472 vrf_table = NULL;
Feng Lu41f44a22015-05-22 11:39:56 +0200473}
474
Feng Lufb2bfc12015-05-22 11:40:08 +0200475/* Create a socket for the VRF. */
476int
477vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
478{
479 int ret = -1;
480
481 if (!vrf_is_enabled (vrf_lookup (vrf_id)))
482 {
483 errno = ENOSYS;
484 return -1;
485 }
486
487 if (vrf_id == VRF_DEFAULT)
488 ret = socket (domain, type, protocol);
489 else
490 errno = ENOSYS;
491
492 return ret;
493}
494