]> git.proxmox.com Git - mirror_frr.git/blame - lib/vrf.c
Merge branch 'stable/2.0'
[mirror_frr.git] / lib / vrf.c
CommitLineData
b72ede27
FL
1/*
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
6a69b354 25#include "if.h"
b72ede27
FL
26#include "vrf.h"
27#include "prefix.h"
28#include "table.h"
29#include "log.h"
30#include "memory.h"
19dc275e
DS
31#include "command.h"
32
4a1ab8e4
DL
33DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
34DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
35
e80e7cce
DL
36DEFINE_QOBJ_TYPE(vrf)
37
1a1a7065 38static __inline int vrf_id_compare (struct vrf *, struct vrf *);
806f8760 39static __inline int vrf_name_compare (struct vrf *, struct vrf *);
1a1a7065
RW
40
41RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
806f8760 42RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare)
1a1a7065
RW
43
44struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
806f8760 45struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name);
1a1a7065 46
19dc275e
DS
47/*
48 * Turn on/off debug code
49 * for vrf.
50 */
51int debug_vrf = 0;
b72ede27 52
b72ede27
FL
53/* Holding VRF hooks */
54struct vrf_master
55{
661512bf
RW
56 int (*vrf_new_hook) (struct vrf *);
57 int (*vrf_delete_hook) (struct vrf *);
58 int (*vrf_enable_hook) (struct vrf *);
59 int (*vrf_disable_hook) (struct vrf *);
b72ede27
FL
60} vrf_master = {0,};
61
e5bf3e1e 62static int vrf_is_enabled (struct vrf *vrf);
e5bf3e1e
FL
63static void vrf_disable (struct vrf *vrf);
64
216b18ef
DS
65/* VRF list existance check by name. */
66struct vrf *
05e8e11e 67vrf_lookup_by_name (const char *name)
216b18ef 68{
806f8760
RW
69 struct vrf vrf;
70 strlcpy (vrf.name, name, sizeof (vrf.name));
71 return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
216b18ef 72}
216b18ef 73
1a1a7065
RW
74static __inline int
75vrf_id_compare (struct vrf *a, struct vrf *b)
b72ede27 76{
1a1a7065 77 return (a->vrf_id - b->vrf_id);
216b18ef
DS
78}
79
806f8760
RW
80static int
81vrf_name_compare (struct vrf *a, struct vrf *b)
b72ede27 82{
806f8760 83 return strcmp (a->name, b->name);
b72ede27
FL
84}
85
216b18ef 86/* Get a VRF. If not found, create one.
34f8e6af
DS
87 * Arg:
88 * name - The name of the vrf. May be NULL if unknown.
89 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
216b18ef 90 * Description: Please note that this routine can be called with just the name
34f8e6af
DS
91 * and 0 vrf-id
92 */
216b18ef
DS
93struct vrf *
94vrf_get (vrf_id_t vrf_id, const char *name)
b72ede27 95{
216b18ef 96 struct vrf *vrf = NULL;
05e8e11e 97 int new = 0;
216b18ef 98
34f8e6af
DS
99 if (debug_vrf)
100 zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
c88a8b75 101
05e8e11e 102 /* Nothing to see, move along here */
34f8e6af
DS
103 if (!name && vrf_id == VRF_UNKNOWN)
104 return NULL;
c88a8b75 105
05e8e11e
RW
106 /* Try to find VRF both by ID and name */
107 if (vrf_id != VRF_UNKNOWN)
108 vrf = vrf_lookup_by_id (vrf_id);
109 if (! vrf && name)
110 vrf = vrf_lookup_by_name (name);
8087b296 111
05e8e11e
RW
112 if (vrf == NULL)
113 {
c88a8b75 114 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
60f1637a 115 vrf->vrf_id = VRF_UNKNOWN;
b2d7c082 116 if_init (&vrf->iflist);
e80e7cce 117 QOBJ_REG (vrf, vrf);
05e8e11e 118 new = 1;
34f8e6af 119
34f8e6af 120 if (debug_vrf)
05e8e11e
RW
121 zlog_debug ("VRF(%u) %s is created.",
122 vrf_id, (name) ? name : "(NULL)");
216b18ef 123 }
05e8e11e
RW
124
125 /* Set identifier */
126 if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN)
34f8e6af 127 {
05e8e11e
RW
128 vrf->vrf_id = vrf_id;
129 RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
34f8e6af 130 }
05e8e11e
RW
131
132 /* Set name */
133 if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name))
c88a8b75 134 {
05e8e11e
RW
135 RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
136 strlcpy (vrf->name, name, sizeof (vrf->name));
137 RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
138 }
139 else if (name && vrf->name[0] == '\0')
140 {
141 strlcpy (vrf->name, name, sizeof (vrf->name));
142 RB_INSERT (vrf_name_head, &vrfs_by_name, vrf);
c88a8b75 143 }
216b18ef 144
05e8e11e 145 if (new && vrf_master.vrf_new_hook)
661512bf 146 (*vrf_master.vrf_new_hook) (vrf);
05e8e11e
RW
147
148 return vrf;
b72ede27
FL
149}
150
151/* Delete a VRF. This is called in vrf_terminate(). */
216b18ef 152void
b72ede27
FL
153vrf_delete (struct vrf *vrf)
154{
19dc275e
DS
155 if (debug_vrf)
156 zlog_debug ("VRF %u is to be deleted.", vrf->vrf_id);
b72ede27 157
e5bf3e1e
FL
158 if (vrf_is_enabled (vrf))
159 vrf_disable (vrf);
160
b72ede27 161 if (vrf_master.vrf_delete_hook)
661512bf 162 (*vrf_master.vrf_delete_hook) (vrf);
216b18ef 163
e80e7cce 164 QOBJ_UNREG (vrf);
3f6d6a5d 165 if_terminate (&vrf->iflist);
b72ede27 166
1a1a7065
RW
167 if (vrf->vrf_id != VRF_UNKNOWN)
168 RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
05e8e11e
RW
169 if (vrf->name[0] != '\0')
170 RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
b72ede27
FL
171
172 XFREE (MTYPE_VRF, vrf);
173}
174
175/* Look up a VRF by identifier. */
216b18ef 176struct vrf *
5f3d1bdf 177vrf_lookup_by_id (vrf_id_t vrf_id)
b72ede27 178{
1a1a7065
RW
179 struct vrf vrf;
180 vrf.vrf_id = vrf_id;
181 return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
b72ede27
FL
182}
183
e5bf3e1e 184/*
05e8e11e 185 * Check whether the VRF is enabled.
e5bf3e1e
FL
186 */
187static int
188vrf_is_enabled (struct vrf *vrf)
189{
79694123 190 return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
e5bf3e1e
FL
191}
192
193/*
194 * Enable a VRF - that is, let the VRF be ready to use.
195 * The VRF_ENABLE_HOOK callback will be called to inform
196 * that they can allocate resources in this VRF.
197 *
198 * RETURN: 1 - enabled successfully; otherwise, 0.
199 */
216b18ef 200int
e5bf3e1e
FL
201vrf_enable (struct vrf *vrf)
202{
05e8e11e
RW
203 if (vrf_is_enabled (vrf))
204 return 1;
205
19dc275e
DS
206 if (debug_vrf)
207 zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
e5bf3e1e 208
05e8e11e 209 SET_FLAG (vrf->status, VRF_ACTIVE);
e5bf3e1e 210
e2b1be64 211 if (vrf_master.vrf_enable_hook)
661512bf 212 (*vrf_master.vrf_enable_hook) (vrf);
e5bf3e1e 213
e2b1be64 214 return 1;
e5bf3e1e
FL
215}
216
217/*
218 * Disable a VRF - that is, let the VRF be unusable.
219 * The VRF_DELETE_HOOK callback will be called to inform
220 * that they must release the resources in the VRF.
221 */
222static void
223vrf_disable (struct vrf *vrf)
224{
05e8e11e
RW
225 if (! vrf_is_enabled (vrf))
226 return;
a647bfa8 227
05e8e11e 228 UNSET_FLAG (vrf->status, VRF_ACTIVE);
e5bf3e1e 229
05e8e11e
RW
230 if (debug_vrf)
231 zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
e5bf3e1e 232
05e8e11e
RW
233 /* Till now, nothing to be done for the default VRF. */
234 //Pending: see why this statement.
e74f14fc 235
05e8e11e 236 if (vrf_master.vrf_disable_hook)
661512bf 237 (*vrf_master.vrf_disable_hook) (vrf);
e5bf3e1e
FL
238}
239
240
b72ede27
FL
241/* Add a VRF hook. Please add hooks before calling vrf_init(). */
242void
661512bf 243vrf_add_hook (int type, int (*func)(struct vrf *))
b72ede27 244{
19dc275e
DS
245 if (debug_vrf)
246 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
247 type, func);
248
b72ede27
FL
249 switch (type) {
250 case VRF_NEW_HOOK:
251 vrf_master.vrf_new_hook = func;
252 break;
253 case VRF_DELETE_HOOK:
254 vrf_master.vrf_delete_hook = func;
255 break;
e5bf3e1e
FL
256 case VRF_ENABLE_HOOK:
257 vrf_master.vrf_enable_hook = func;
258 break;
259 case VRF_DISABLE_HOOK:
260 vrf_master.vrf_disable_hook = func;
261 break;
b72ede27
FL
262 default:
263 break;
264 }
265}
266
216b18ef
DS
267vrf_id_t
268vrf_name_to_id (const char *name)
269{
270 struct vrf *vrf;
271 vrf_id_t vrf_id = VRF_DEFAULT; //Pending: need a way to return invalid id/ routine not used.
272
273 vrf = vrf_lookup_by_name (name);
274 if (vrf)
275 vrf_id = vrf->vrf_id;
276
277 return vrf_id;
278}
279
b72ede27
FL
280/* Get the data pointer of the specified VRF. If not found, create one. */
281void *
282vrf_info_get (vrf_id_t vrf_id)
283{
216b18ef 284 struct vrf *vrf = vrf_get (vrf_id, NULL);
b72ede27
FL
285 return vrf->info;
286}
287
288/* Look up the data pointer of the specified VRF. */
289void *
290vrf_info_lookup (vrf_id_t vrf_id)
291{
5f3d1bdf 292 struct vrf *vrf = vrf_lookup_by_id (vrf_id);
b72ede27
FL
293 return vrf ? vrf->info : NULL;
294}
295
8736158a
FL
296/* Look up the interface list in a VRF. */
297struct list *
298vrf_iflist (vrf_id_t vrf_id)
299{
5f3d1bdf 300 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
8736158a
FL
301 return vrf ? vrf->iflist : NULL;
302}
303
304/* Get the interface list of the specified VRF. Create one if not find. */
305struct list *
306vrf_iflist_get (vrf_id_t vrf_id)
307{
216b18ef 308 struct vrf * vrf = vrf_get (vrf_id, NULL);
8736158a
FL
309 return vrf->iflist;
310}
311
b33adb7c 312/* Create the interface list for the specified VRF, if needed. */
313void
314vrf_iflist_create (vrf_id_t vrf_id)
315{
5f3d1bdf 316 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
b33adb7c 317 if (vrf && !vrf->iflist)
b2d7c082 318 if_init (&vrf->iflist);
b33adb7c 319}
320
009b18fc 321/* Free the interface list of the specified VRF. */
322void
323vrf_iflist_terminate (vrf_id_t vrf_id)
324{
5f3d1bdf 325 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
009b18fc 326 if (vrf && vrf->iflist)
b2d7c082 327 if_terminate (&vrf->iflist);
009b18fc 328}
329
7076bb2f
FL
330/*
331 * VRF bit-map
332 */
333
334#define VRF_BITMAP_NUM_OF_GROUPS 8
335#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
336 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
337#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
338 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
339
340#define VRF_BITMAP_GROUP(_id) \
341 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
342#define VRF_BITMAP_BIT_OFFSET(_id) \
343 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
344
345#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
346 ((_bit_offset) / CHAR_BIT)
347#define VRF_BITMAP_FLAG(_bit_offset) \
348 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
349
350struct vrf_bitmap
351{
352 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
353};
354
355vrf_bitmap_t
356vrf_bitmap_init (void)
357{
358 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
359}
360
361void
362vrf_bitmap_free (vrf_bitmap_t bmap)
363{
364 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
365 int i;
366
367 if (bmap == VRF_BITMAP_NULL)
368 return;
369
370 for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
371 if (bm->groups[i])
372 XFREE (MTYPE_VRF_BITMAP, bm->groups[i]);
373
374 XFREE (MTYPE_VRF_BITMAP, bm);
375}
376
377void
378vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
379{
380 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
381 u_char group = VRF_BITMAP_GROUP (vrf_id);
382 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
383
384 if (bmap == VRF_BITMAP_NULL)
385 return;
386
387 if (bm->groups[group] == NULL)
388 bm->groups[group] = XCALLOC (MTYPE_VRF_BITMAP,
389 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
390
391 SET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
392 VRF_BITMAP_FLAG (offset));
393}
394
395void
396vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
397{
398 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
399 u_char group = VRF_BITMAP_GROUP (vrf_id);
400 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
401
402 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
403 return;
404
405 UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
406 VRF_BITMAP_FLAG (offset));
407}
408
409int
410vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
411{
412 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
413 u_char group = VRF_BITMAP_GROUP (vrf_id);
414 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
415
416 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
417 return 0;
418
419 return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
420 VRF_BITMAP_FLAG (offset)) ? 1 : 0;
421}
422
b72ede27
FL
423/* Initialize VRF module. */
424void
425vrf_init (void)
426{
427 struct vrf *default_vrf;
428
19dc275e
DS
429 if (debug_vrf)
430 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
431
b72ede27 432 /* The default VRF always exists. */
216b18ef 433 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
b72ede27
FL
434 if (!default_vrf)
435 {
436 zlog_err ("vrf_init: failed to create the default VRF!");
437 exit (1);
438 }
439
e5bf3e1e
FL
440 /* Enable the default VRF. */
441 if (!vrf_enable (default_vrf))
442 {
443 zlog_err ("vrf_init: failed to enable the default VRF!");
444 exit (1);
445 }
b72ede27
FL
446}
447
448/* Terminate VRF module. */
449void
450vrf_terminate (void)
451{
b72ede27
FL
452 struct vrf *vrf;
453
19dc275e
DS
454 if (debug_vrf)
455 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
456
1a1a7065
RW
457 while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
458 vrf_delete (vrf);
05e8e11e
RW
459 while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
460 vrf_delete (vrf);
b72ede27
FL
461}
462
e5bf3e1e
FL
463/* Create a socket for the VRF. */
464int
465vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
466{
467 int ret = -1;
468
19dc275e 469 ret = socket (domain, type, protocol);
e5bf3e1e
FL
470
471 return ret;
472}
473
f30c50b9
RW
474/* vrf CLI commands */
475DEFUN (vrf,
476 vrf_cmd,
477 "vrf NAME",
478 "Select a VRF to configure\n"
479 "VRF's name\n")
480{
53dc2b05
DL
481 int idx_name = 1;
482 const char *vrfname = argv[idx_name]->arg;
483
f30c50b9
RW
484 struct vrf *vrfp;
485 size_t sl;
486
53dc2b05 487 if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
f30c50b9
RW
488 {
489 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
53dc2b05
DL
490 "%d characters%s",
491 vrfname, VRF_NAMSIZ, VTY_NEWLINE);
f30c50b9
RW
492 return CMD_WARNING;
493 }
494
53dc2b05 495 vrfp = vrf_get (VRF_UNKNOWN, vrfname);
f30c50b9
RW
496
497 VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp);
498
499 return CMD_SUCCESS;
500}
501
502DEFUN_NOSH (no_vrf,
503 no_vrf_cmd,
504 "no vrf NAME",
505 NO_STR
506 "Delete a pseudo VRF's configuration\n"
507 "VRF's name\n")
508{
53dc2b05
DL
509 const char *vrfname = argv[2]->arg;
510
f30c50b9
RW
511 struct vrf *vrfp;
512
53dc2b05 513 vrfp = vrf_lookup_by_name (vrfname);
f30c50b9
RW
514
515 if (vrfp == NULL)
516 {
53dc2b05 517 vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
f30c50b9
RW
518 return CMD_WARNING;
519 }
520
521 if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
522 {
523 vty_out (vty, "%% Only inactive VRFs can be deleted%s",
53dc2b05 524 VTY_NEWLINE);
f30c50b9
RW
525 return CMD_WARNING;
526 }
527
528 vrf_delete(vrfp);
529
530 return CMD_SUCCESS;
531}
532
53dc2b05 533
19dc275e
DS
534/*
535 * Debug CLI for vrf's
536 */
537DEFUN (vrf_debug,
538 vrf_debug_cmd,
539 "debug vrf",
540 DEBUG_STR
541 "VRF Debugging\n")
542{
543 debug_vrf = 1;
544
545 return CMD_SUCCESS;
546}
547
548DEFUN (no_vrf_debug,
549 no_vrf_debug_cmd,
550 "no debug vrf",
551 NO_STR
552 DEBUG_STR
553 "VRF Debugging\n")
554{
555 debug_vrf = 0;
556
557 return CMD_SUCCESS;
558}
559
560static int
561vrf_write_host (struct vty *vty)
562{
563 if (debug_vrf)
564 vty_out (vty, "debug vrf%s", VTY_NEWLINE);
565
566 return 1;
567}
568
569static struct cmd_node vrf_debug_node =
570{
571 VRF_DEBUG_NODE,
572 "",
573 1
574};
575
576void
577vrf_install_commands (void)
578{
579 install_node (&vrf_debug_node, vrf_write_host);
580
581 install_element (CONFIG_NODE, &vrf_debug_cmd);
582 install_element (ENABLE_NODE, &vrf_debug_cmd);
583 install_element (CONFIG_NODE, &no_vrf_debug_cmd);
584 install_element (ENABLE_NODE, &no_vrf_debug_cmd);
53dc2b05
DL
585
586 install_element (CONFIG_NODE, &vrf_cmd);
587 install_element (CONFIG_NODE, &no_vrf_cmd);
19dc275e 588}