]> git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
Merge pull request #70 from pguibert6WIND/frr_6wind_vpnv6_2
[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 || vrf_id == VRF_UNKNOWN)
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 || vrf_id == VRF_UNKNOWN ||
403 bm->groups[group] == NULL)
404 return;
405
406 UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
407 VRF_BITMAP_FLAG (offset));
408 }
409
410 int
411 vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
412 {
413 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
414 u_char group = VRF_BITMAP_GROUP (vrf_id);
415 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
416
417 if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN ||
418 bm->groups[group] == NULL)
419 return 0;
420
421 return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
422 VRF_BITMAP_FLAG (offset)) ? 1 : 0;
423 }
424
425 /* Initialize VRF module. */
426 void
427 vrf_init (void)
428 {
429 struct vrf *default_vrf;
430
431 if (debug_vrf)
432 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
433
434 /* The default VRF always exists. */
435 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
436 if (!default_vrf)
437 {
438 zlog_err ("vrf_init: failed to create the default VRF!");
439 exit (1);
440 }
441
442 /* Enable the default VRF. */
443 if (!vrf_enable (default_vrf))
444 {
445 zlog_err ("vrf_init: failed to enable the default VRF!");
446 exit (1);
447 }
448 }
449
450 /* Terminate VRF module. */
451 void
452 vrf_terminate (void)
453 {
454 struct vrf *vrf;
455
456 if (debug_vrf)
457 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
458
459 while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
460 vrf_delete (vrf);
461 while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL)
462 vrf_delete (vrf);
463 }
464
465 /* Create a socket for the VRF. */
466 int
467 vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
468 {
469 int ret = -1;
470
471 ret = socket (domain, type, protocol);
472
473 return ret;
474 }
475
476 /* vrf CLI commands */
477 DEFUN (vrf,
478 vrf_cmd,
479 "vrf NAME",
480 "Select a VRF to configure\n"
481 "VRF's name\n")
482 {
483 int idx_name = 1;
484 const char *vrfname = argv[idx_name]->arg;
485
486 struct vrf *vrfp;
487 size_t sl;
488
489 if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
490 {
491 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
492 "%d characters%s",
493 vrfname, VRF_NAMSIZ, VTY_NEWLINE);
494 return CMD_WARNING;
495 }
496
497 vrfp = vrf_get (VRF_UNKNOWN, vrfname);
498
499 VTY_PUSH_CONTEXT (VRF_NODE, vrfp);
500
501 return CMD_SUCCESS;
502 }
503
504 DEFUN_NOSH (no_vrf,
505 no_vrf_cmd,
506 "no vrf NAME",
507 NO_STR
508 "Delete a pseudo VRF's configuration\n"
509 "VRF's name\n")
510 {
511 const char *vrfname = argv[2]->arg;
512
513 struct vrf *vrfp;
514
515 vrfp = vrf_lookup_by_name (vrfname);
516
517 if (vrfp == NULL)
518 {
519 vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
520 return CMD_WARNING;
521 }
522
523 if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
524 {
525 vty_out (vty, "%% Only inactive VRFs can be deleted%s",
526 VTY_NEWLINE);
527 return CMD_WARNING;
528 }
529
530 vrf_delete(vrfp);
531
532 return CMD_SUCCESS;
533 }
534
535
536 struct cmd_node vrf_node =
537 {
538 VRF_NODE,
539 "%s(config-vrf)# ",
540 1
541 };
542
543 /*
544 * Debug CLI for vrf's
545 */
546 DEFUN (vrf_debug,
547 vrf_debug_cmd,
548 "debug vrf",
549 DEBUG_STR
550 "VRF Debugging\n")
551 {
552 debug_vrf = 1;
553
554 return CMD_SUCCESS;
555 }
556
557 DEFUN (no_vrf_debug,
558 no_vrf_debug_cmd,
559 "no debug vrf",
560 NO_STR
561 DEBUG_STR
562 "VRF Debugging\n")
563 {
564 debug_vrf = 0;
565
566 return CMD_SUCCESS;
567 }
568
569 static int
570 vrf_write_host (struct vty *vty)
571 {
572 if (debug_vrf)
573 vty_out (vty, "debug vrf%s", VTY_NEWLINE);
574
575 return 1;
576 }
577
578 static struct cmd_node vrf_debug_node =
579 {
580 VRF_DEBUG_NODE,
581 "",
582 1
583 };
584
585 void
586 vrf_install_commands (void)
587 {
588 install_node (&vrf_debug_node, vrf_write_host);
589
590 install_element (CONFIG_NODE, &vrf_debug_cmd);
591 install_element (ENABLE_NODE, &vrf_debug_cmd);
592 install_element (CONFIG_NODE, &no_vrf_debug_cmd);
593 install_element (ENABLE_NODE, &no_vrf_debug_cmd);
594 }
595
596 void
597 vrf_cmd_init (int (*writefunc)(struct vty *vty))
598 {
599 install_element (CONFIG_NODE, &vrf_cmd);
600 install_element (CONFIG_NODE, &no_vrf_cmd);
601 install_node (&vrf_node, writefunc);
602 install_default (VRF_NODE);
603 }