]> git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
pimd: make the json output a bit more machine-friendly
[mirror_frr.git] / lib / vrf.c
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
25 #include "if.h"
26 #include "vrf.h"
27 #include "prefix.h"
28 #include "table.h"
29 #include "log.h"
30 #include "memory.h"
31 #include "command.h"
32
33 DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
34 DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
35
36 DEFINE_QOBJ_TYPE(vrf)
37
38 static __inline int vrf_id_compare (struct vrf *, struct vrf *);
39 static __inline int vrf_name_compare (struct vrf *, struct vrf *);
40
41 RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
42 RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare)
43
44 struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
45 struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name);
46
47 /*
48 * Turn on/off debug code
49 * for vrf.
50 */
51 int debug_vrf = 0;
52
53 /* Holding VRF hooks */
54 struct vrf_master
55 {
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 *);
60 } vrf_master = {0,};
61
62 static int vrf_is_enabled (struct vrf *vrf);
63 static void vrf_disable (struct vrf *vrf);
64
65 /* VRF list existance check by name. */
66 struct vrf *
67 vrf_lookup_by_name (const char *name)
68 {
69 struct vrf vrf;
70 strlcpy (vrf.name, name, sizeof (vrf.name));
71 return (RB_FIND (vrf_name_head, &vrfs_by_name, &vrf));
72 }
73
74 static __inline int
75 vrf_id_compare (struct vrf *a, struct vrf *b)
76 {
77 return (a->vrf_id - b->vrf_id);
78 }
79
80 static int
81 vrf_name_compare (struct vrf *a, struct vrf *b)
82 {
83 return strcmp (a->name, b->name);
84 }
85
86 /* Get a VRF. If not found, create one.
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
90 * Description: Please note that this routine can be called with just the name
91 * and 0 vrf-id
92 */
93 struct vrf *
94 vrf_get (vrf_id_t vrf_id, const char *name)
95 {
96 struct vrf *vrf = NULL;
97 int new = 0;
98
99 if (debug_vrf)
100 zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
101
102 /* Nothing to see, move along here */
103 if (!name && vrf_id == VRF_UNKNOWN)
104 return NULL;
105
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);
111
112 if (vrf == NULL)
113 {
114 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
115 vrf->vrf_id = VRF_UNKNOWN;
116 if_init (&vrf->iflist);
117 QOBJ_REG (vrf, vrf);
118 new = 1;
119
120 if (debug_vrf)
121 zlog_debug ("VRF(%u) %s is created.",
122 vrf_id, (name) ? name : "(NULL)");
123 }
124
125 /* Set identifier */
126 if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN)
127 {
128 vrf->vrf_id = vrf_id;
129 RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
130 }
131
132 /* Set name */
133 if (name && vrf->name[0] != '\0' && strcmp (name, vrf->name))
134 {
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);
143 }
144
145 if (new && vrf_master.vrf_new_hook)
146 (*vrf_master.vrf_new_hook) (vrf);
147
148 return vrf;
149 }
150
151 /* Delete a VRF. This is called in vrf_terminate(). */
152 void
153 vrf_delete (struct vrf *vrf)
154 {
155 if (debug_vrf)
156 zlog_debug ("VRF %u is to be deleted.", vrf->vrf_id);
157
158 if (vrf_is_enabled (vrf))
159 vrf_disable (vrf);
160
161 if (vrf_master.vrf_delete_hook)
162 (*vrf_master.vrf_delete_hook) (vrf);
163
164 QOBJ_UNREG (vrf);
165 if_terminate (&vrf->iflist);
166
167 if (vrf->vrf_id != VRF_UNKNOWN)
168 RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
169 if (vrf->name[0] != '\0')
170 RB_REMOVE (vrf_name_head, &vrfs_by_name, vrf);
171
172 XFREE (MTYPE_VRF, vrf);
173 }
174
175 /* Look up a VRF by identifier. */
176 struct vrf *
177 vrf_lookup_by_id (vrf_id_t vrf_id)
178 {
179 struct vrf vrf;
180 vrf.vrf_id = vrf_id;
181 return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
182 }
183
184 /*
185 * Check whether the VRF is enabled.
186 */
187 static int
188 vrf_is_enabled (struct vrf *vrf)
189 {
190 return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
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 */
200 int
201 vrf_enable (struct vrf *vrf)
202 {
203 if (vrf_is_enabled (vrf))
204 return 1;
205
206 if (debug_vrf)
207 zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
208
209 SET_FLAG (vrf->status, VRF_ACTIVE);
210
211 if (vrf_master.vrf_enable_hook)
212 (*vrf_master.vrf_enable_hook) (vrf);
213
214 return 1;
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 */
222 static void
223 vrf_disable (struct vrf *vrf)
224 {
225 if (! vrf_is_enabled (vrf))
226 return;
227
228 UNSET_FLAG (vrf->status, VRF_ACTIVE);
229
230 if (debug_vrf)
231 zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
232
233 /* Till now, nothing to be done for the default VRF. */
234 //Pending: see why this statement.
235
236 if (vrf_master.vrf_disable_hook)
237 (*vrf_master.vrf_disable_hook) (vrf);
238 }
239
240
241 /* Add a VRF hook. Please add hooks before calling vrf_init(). */
242 void
243 vrf_add_hook (int type, int (*func)(struct vrf *))
244 {
245 if (debug_vrf)
246 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
247 type, func);
248
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;
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;
262 default:
263 break;
264 }
265 }
266
267 vrf_id_t
268 vrf_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
280 /* Get the data pointer of the specified VRF. If not found, create one. */
281 void *
282 vrf_info_get (vrf_id_t vrf_id)
283 {
284 struct vrf *vrf = vrf_get (vrf_id, NULL);
285 return vrf->info;
286 }
287
288 /* Look up the data pointer of the specified VRF. */
289 void *
290 vrf_info_lookup (vrf_id_t vrf_id)
291 {
292 struct vrf *vrf = vrf_lookup_by_id (vrf_id);
293 return vrf ? vrf->info : NULL;
294 }
295
296 /* Look up the interface list in a VRF. */
297 struct list *
298 vrf_iflist (vrf_id_t vrf_id)
299 {
300 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
301 return vrf ? vrf->iflist : NULL;
302 }
303
304 /* Get the interface list of the specified VRF. Create one if not find. */
305 struct list *
306 vrf_iflist_get (vrf_id_t vrf_id)
307 {
308 struct vrf * vrf = vrf_get (vrf_id, NULL);
309 return vrf->iflist;
310 }
311
312 /* Create the interface list for the specified VRF, if needed. */
313 void
314 vrf_iflist_create (vrf_id_t vrf_id)
315 {
316 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
317 if (vrf && !vrf->iflist)
318 if_init (&vrf->iflist);
319 }
320
321 /* Free the interface list of the specified VRF. */
322 void
323 vrf_iflist_terminate (vrf_id_t vrf_id)
324 {
325 struct vrf * vrf = vrf_lookup_by_id (vrf_id);
326 if (vrf && vrf->iflist)
327 if_terminate (&vrf->iflist);
328 }
329
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
350 struct vrf_bitmap
351 {
352 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
353 };
354
355 vrf_bitmap_t
356 vrf_bitmap_init (void)
357 {
358 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
359 }
360
361 void
362 vrf_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
377 void
378 vrf_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
395 void
396 vrf_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
409 int
410 vrf_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
423 /* Initialize VRF module. */
424 void
425 vrf_init (void)
426 {
427 struct vrf *default_vrf;
428
429 if (debug_vrf)
430 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
431
432 /* The default VRF always exists. */
433 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
434 if (!default_vrf)
435 {
436 zlog_err ("vrf_init: failed to create the default VRF!");
437 exit (1);
438 }
439
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 }
446 }
447
448 /* Terminate VRF module. */
449 void
450 vrf_terminate (void)
451 {
452 struct vrf *vrf;
453
454 if (debug_vrf)
455 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
456
457 while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
458 vrf_delete (vrf);
459 while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
460 vrf_delete (vrf);
461 }
462
463 /* Create a socket for the VRF. */
464 int
465 vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
466 {
467 int ret = -1;
468
469 ret = socket (domain, type, protocol);
470
471 return ret;
472 }
473
474 /* vrf CLI commands */
475 DEFUN (vrf,
476 vrf_cmd,
477 "vrf NAME",
478 "Select a VRF to configure\n"
479 "VRF's name\n")
480 {
481 int idx_name = 1;
482 const char *vrfname = argv[idx_name]->arg;
483
484 struct vrf *vrfp;
485 size_t sl;
486
487 if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
488 {
489 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
490 "%d characters%s",
491 vrfname, VRF_NAMSIZ, VTY_NEWLINE);
492 return CMD_WARNING;
493 }
494
495 vrfp = vrf_get (VRF_UNKNOWN, vrfname);
496
497 VTY_PUSH_CONTEXT (VRF_NODE, vrfp);
498
499 return CMD_SUCCESS;
500 }
501
502 DEFUN_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 {
509 const char *vrfname = argv[2]->arg;
510
511 struct vrf *vrfp;
512
513 vrfp = vrf_lookup_by_name (vrfname);
514
515 if (vrfp == NULL)
516 {
517 vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
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",
524 VTY_NEWLINE);
525 return CMD_WARNING;
526 }
527
528 vrf_delete(vrfp);
529
530 return CMD_SUCCESS;
531 }
532
533
534 struct cmd_node vrf_node =
535 {
536 VRF_NODE,
537 "%s(config-vrf)# ",
538 1
539 };
540
541 /*
542 * Debug CLI for vrf's
543 */
544 DEFUN (vrf_debug,
545 vrf_debug_cmd,
546 "debug vrf",
547 DEBUG_STR
548 "VRF Debugging\n")
549 {
550 debug_vrf = 1;
551
552 return CMD_SUCCESS;
553 }
554
555 DEFUN (no_vrf_debug,
556 no_vrf_debug_cmd,
557 "no debug vrf",
558 NO_STR
559 DEBUG_STR
560 "VRF Debugging\n")
561 {
562 debug_vrf = 0;
563
564 return CMD_SUCCESS;
565 }
566
567 static int
568 vrf_write_host (struct vty *vty)
569 {
570 if (debug_vrf)
571 vty_out (vty, "debug vrf%s", VTY_NEWLINE);
572
573 return 1;
574 }
575
576 static struct cmd_node vrf_debug_node =
577 {
578 VRF_DEBUG_NODE,
579 "",
580 1
581 };
582
583 void
584 vrf_install_commands (void)
585 {
586 install_node (&vrf_debug_node, vrf_write_host);
587
588 install_element (CONFIG_NODE, &vrf_debug_cmd);
589 install_element (ENABLE_NODE, &vrf_debug_cmd);
590 install_element (CONFIG_NODE, &no_vrf_debug_cmd);
591 install_element (ENABLE_NODE, &no_vrf_debug_cmd);
592 }
593
594 void
595 vrf_cmd_init (int (*writefunc)(struct vty *vty))
596 {
597 install_element (CONFIG_NODE, &vrf_cmd);
598 install_element (CONFIG_NODE, &no_vrf_cmd);
599 install_node (&vrf_node, writefunc);
600 install_default (VRF_NODE);
601 }