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