]> git.proxmox.com Git - mirror_frr.git/blame - lib/vrf.c
vtysh: Fix vrf submode to call correct daemons
[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"
31
b72ede27
FL
32/* Holding VRF hooks */
33struct vrf_master
34{
216b18ef
DS
35 int (*vrf_new_hook) (vrf_id_t, const char *, void **);
36 int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
37 int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
38 int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
b72ede27
FL
39} vrf_master = {0,};
40
41/* VRF table */
42struct route_table *vrf_table = NULL;
43
216b18ef
DS
44/* VRF is part of a list too to store it before its actually active */
45struct list *vrf_list;
46
e5bf3e1e 47static int vrf_is_enabled (struct vrf *vrf);
e5bf3e1e
FL
48static void vrf_disable (struct vrf *vrf);
49
216b18ef
DS
50/* VRF list existance check by name. */
51struct vrf *
52vrf_list_lookup_by_name (const char *name)
53{
54 struct listnode *node;
55 struct vrf *vrfp;
56
57 if (name)
58 for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
59 {
60 if (strcmp(name, vrfp->name) == 0)
61 return vrfp;
62 }
63 return NULL;
64}
65
66struct vrf *
67vrf_list_lookup_by_name_len (const char *name, size_t namelen)
68{
69 struct listnode *node;
70 struct vrf *vrfp;
71
72 if (namelen > INTERFACE_NAMSIZ)
73 return NULL;
74
75 for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
76 {
77 if (!memcmp(name, vrfp->name, namelen) && (vrfp->name[namelen] == '\0'))
78 return vrfp;
79 }
80 return NULL;
81}
82
83/* Create new interface structure. */
84struct vrf *
85vrf_create (const char *name, size_t namelen)
86{
87 struct vrf *vrfp;
88
89 vrfp = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
90
91 assert (name);
92 assert (namelen <= VRF_NAMSIZ); /* Need space for '\0' at end. */
93 strncpy (vrfp->name, name, namelen);
94 vrfp->name[namelen] = '\0';
95 if (vrf_list_lookup_by_name (vrfp->name) == NULL)
96 listnode_add_sort (vrf_list, vrfp);
97 else
98 zlog_err("vrf_create(%s): corruption detected -- vrf with this "
99 "name exists already with vrf-id %u!", vrfp->name, vrfp->vrf_id);
100
101 UNSET_FLAG(vrfp->status, ZEBRA_VRF_ACTIVE);
102
103 /* Pending: - Make sure this 0 vrf-id isnt taken as default vrf
104 - See if calling the the new_hook here is ok, may need to make the attached callback re-entrant.
105 if (vrf_master.vrf_new_hook)
106 (*vrf_master.vrf_new_hook) (0, name, &vrfp->info);
107 */
108 return vrfp;
109}
110
111struct vrf *
112vrf_get_by_name_len (const char *name, size_t namelen)
113{
114 struct vrf *vrfp;
115
116 return ((vrfp = vrf_list_lookup_by_name_len (name, namelen)) != NULL) ? vrfp :
117 vrf_create (name, namelen);
118}
119
120struct vrf *
121vrf_get_by_name (const char *name)
122{
123 struct vrf *vrfp;
124
125 return ((vrfp = vrf_list_lookup_by_name (name)) != NULL) ? vrfp :
126 vrf_create (name, strlen(name));
127}
e5bf3e1e 128
b72ede27
FL
129/* Build the table key */
130static void
131vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
132{
133 p->family = AF_INET;
134 p->prefixlen = IPV4_MAX_BITLEN;
135 p->u.prefix4.s_addr = vrf_id;
136}
137
216b18ef
DS
138/* Get a VRF. If not found, create one.
139 * Arg: name
140 * Description: Please note that this routine can be called with just the name
141 and 0 vrf-id */
142struct vrf *
143vrf_get (vrf_id_t vrf_id, const char *name)
b72ede27
FL
144{
145 struct prefix p;
146 struct route_node *rn;
216b18ef 147 struct vrf *vrf = NULL;
b72ede27
FL
148
149 vrf_build_key (vrf_id, &p);
150 rn = route_node_get (vrf_table, &p);
151 if (rn->info)
152 {
153 vrf = (struct vrf *)rn->info;
154 route_unlock_node (rn); /* get */
216b18ef
DS
155
156 if (name)
157 {
158 strncpy (vrf->name, name, strlen(name));
159 vrf->name[strlen(name)] = '\0';
160 if (vrf_list_lookup_by_name (vrf->name) == NULL)
161 listnode_add_sort (vrf_list, vrf);
162 }
b72ede27 163 }
216b18ef
DS
164 else
165 {
166 if (name)
167 vrf = vrf_get_by_name(name);
b72ede27 168
216b18ef
DS
169 if (!vrf)
170 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
b72ede27 171
216b18ef
DS
172 vrf->vrf_id = vrf_id;
173 rn->info = vrf;
174 vrf->node = rn;
8736158a 175
216b18ef
DS
176 /* Initialize interfaces. */
177 if_init (vrf_id, &vrf->iflist);
178 }
b72ede27 179
216b18ef
DS
180 if (name)
181 zlog_info ("VRF %s with id %u is created.", name, vrf_id);
182 else
183 zlog_info ("VRF %u is created.", vrf_id);
b72ede27 184
216b18ef
DS
185 if (vrf_master.vrf_new_hook && name) {
186 (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
187
188 if (vrf->info)
189 zlog_info ("zvrf is created.");
190 }
b72ede27
FL
191 return vrf;
192}
193
194/* Delete a VRF. This is called in vrf_terminate(). */
216b18ef 195void
b72ede27
FL
196vrf_delete (struct vrf *vrf)
197{
198 zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
199
e5bf3e1e
FL
200 if (vrf_is_enabled (vrf))
201 vrf_disable (vrf);
202
b72ede27 203 if (vrf_master.vrf_delete_hook)
216b18ef
DS
204 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
205
206 if (CHECK_FLAG (vrf->status, ZEBRA_VRF_ACTIVE))
207 if_terminate (vrf->vrf_id, &vrf->iflist);
b72ede27 208
216b18ef
DS
209 if (vrf->node)
210 {
211 vrf->node->info = NULL;
212 route_unlock_node(vrf->node);
213 }
8736158a 214
216b18ef 215 listnode_delete (vrf_list, vrf);
b72ede27
FL
216
217 XFREE (MTYPE_VRF, vrf);
218}
219
220/* Look up a VRF by identifier. */
216b18ef 221struct vrf *
b72ede27
FL
222vrf_lookup (vrf_id_t vrf_id)
223{
224 struct prefix p;
225 struct route_node *rn;
226 struct vrf *vrf = NULL;
227
228 vrf_build_key (vrf_id, &p);
229 rn = route_node_lookup (vrf_table, &p);
230 if (rn)
231 {
232 vrf = (struct vrf *)rn->info;
233 route_unlock_node (rn); /* lookup */
234 }
235 return vrf;
236}
237
e5bf3e1e
FL
238/*
239 * Check whether the VRF is enabled - that is, whether the VRF
240 * is ready to allocate resources. Currently there's only one
241 * type of resource: socket.
242 */
243static int
244vrf_is_enabled (struct vrf *vrf)
245{
216b18ef
DS
246 return vrf && CHECK_FLAG (vrf->status, ZEBRA_VRF_ACTIVE);
247
248 /*Pending: figure out the real use of this routine.. it used to be..
e5bf3e1e 249 return vrf && vrf->vrf_id == VRF_DEFAULT;
216b18ef 250 */
e5bf3e1e
FL
251}
252
253/*
254 * Enable a VRF - that is, let the VRF be ready to use.
255 * The VRF_ENABLE_HOOK callback will be called to inform
256 * that they can allocate resources in this VRF.
257 *
258 * RETURN: 1 - enabled successfully; otherwise, 0.
259 */
216b18ef 260int
e5bf3e1e
FL
261vrf_enable (struct vrf *vrf)
262{
216b18ef
DS
263//Pending: see if VRF lib had a reason to leave it for default only
264// /* Till now, only the default VRF can be enabled. */
265// if (vrf->vrf_id == VRF_DEFAULT)
266// {
e5bf3e1e
FL
267 zlog_info ("VRF %u is enabled.", vrf->vrf_id);
268
269 if (vrf_master.vrf_enable_hook)
216b18ef 270 (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
e5bf3e1e
FL
271
272 return 1;
216b18ef 273// }
e5bf3e1e 274
216b18ef 275// return 0;
e5bf3e1e
FL
276}
277
278/*
279 * Disable a VRF - that is, let the VRF be unusable.
280 * The VRF_DELETE_HOOK callback will be called to inform
281 * that they must release the resources in the VRF.
282 */
283static void
284vrf_disable (struct vrf *vrf)
285{
286 if (vrf_is_enabled (vrf))
287 {
288 zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
289
290 /* Till now, nothing to be done for the default VRF. */
216b18ef 291 //Pending: see why this statement.
e5bf3e1e
FL
292
293 if (vrf_master.vrf_disable_hook)
216b18ef 294 (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
e5bf3e1e
FL
295 }
296}
297
298
b72ede27
FL
299/* Add a VRF hook. Please add hooks before calling vrf_init(). */
300void
216b18ef 301vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
b72ede27
FL
302{
303 switch (type) {
304 case VRF_NEW_HOOK:
305 vrf_master.vrf_new_hook = func;
306 break;
307 case VRF_DELETE_HOOK:
308 vrf_master.vrf_delete_hook = func;
309 break;
e5bf3e1e
FL
310 case VRF_ENABLE_HOOK:
311 vrf_master.vrf_enable_hook = func;
312 break;
313 case VRF_DISABLE_HOOK:
314 vrf_master.vrf_disable_hook = func;
315 break;
b72ede27
FL
316 default:
317 break;
318 }
319}
320
321/* Return the iterator of the first VRF. */
322vrf_iter_t
323vrf_first (void)
324{
325 struct route_node *rn;
326
327 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
328 if (rn->info)
329 {
330 route_unlock_node (rn); /* top/next */
331 return (vrf_iter_t)rn;
332 }
333 return VRF_ITER_INVALID;
334}
335
336/* Return the next VRF iterator to the given iterator. */
337vrf_iter_t
338vrf_next (vrf_iter_t iter)
339{
340 struct route_node *rn = NULL;
341
342 /* Lock it first because route_next() will unlock it. */
343 if (iter != VRF_ITER_INVALID)
344 rn = route_next (route_lock_node ((struct route_node *)iter));
345
346 for (; rn; rn = route_next (rn))
347 if (rn->info)
348 {
349 route_unlock_node (rn); /* next */
350 return (vrf_iter_t)rn;
351 }
352 return VRF_ITER_INVALID;
353}
354
355/* Return the VRF iterator of the given VRF ID. If it does not exist,
356 * the iterator of the next existing VRF is returned. */
357vrf_iter_t
358vrf_iterator (vrf_id_t vrf_id)
359{
360 struct prefix p;
361 struct route_node *rn;
362
363 vrf_build_key (vrf_id, &p);
364 rn = route_node_get (vrf_table, &p);
365 if (rn->info)
366 {
367 /* OK, the VRF exists. */
368 route_unlock_node (rn); /* get */
369 return (vrf_iter_t)rn;
370 }
371
372 /* Find the next VRF. */
373 for (rn = route_next (rn); rn; rn = route_next (rn))
374 if (rn->info)
375 {
376 route_unlock_node (rn); /* next */
377 return (vrf_iter_t)rn;
378 }
379
380 return VRF_ITER_INVALID;
381}
382
383/* Obtain the VRF ID from the given VRF iterator. */
384vrf_id_t
385vrf_iter2id (vrf_iter_t iter)
386{
387 struct route_node *rn = (struct route_node *) iter;
388 return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
389}
390
216b18ef
DS
391struct vrf *
392vrf_iter2vrf (vrf_iter_t iter)
393{
394 struct route_node *rn = (struct route_node *) iter;
395 return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
396}
397
b72ede27
FL
398/* Obtain the data pointer from the given VRF iterator. */
399void *
400vrf_iter2info (vrf_iter_t iter)
401{
402 struct route_node *rn = (struct route_node *) iter;
403 return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
404}
405
8736158a
FL
406/* Obtain the interface list from the given VRF iterator. */
407struct list *
408vrf_iter2iflist (vrf_iter_t iter)
409{
410 struct route_node *rn = (struct route_node *) iter;
411 return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
412}
413
216b18ef
DS
414/* Look up a VRF by name. */
415struct vrf *
416vrf_lookup_by_name (const char *name)
417{
418 struct vrf *vrf = NULL;
419 vrf_iter_t iter;
420
421 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
422 {
423 vrf = vrf_iter2vrf (iter);
424 if (vrf && !strcmp(vrf->name, name))
425 break;
426 }
427
428 return vrf;
429}
430
431vrf_id_t
432vrf_name_to_id (const char *name)
433{
434 struct vrf *vrf;
435 vrf_id_t vrf_id = VRF_DEFAULT; //Pending: need a way to return invalid id/ routine not used.
436
437 vrf = vrf_lookup_by_name (name);
438 if (vrf)
439 vrf_id = vrf->vrf_id;
440
441 return vrf_id;
442}
443
b72ede27
FL
444/* Get the data pointer of the specified VRF. If not found, create one. */
445void *
446vrf_info_get (vrf_id_t vrf_id)
447{
216b18ef 448 struct vrf *vrf = vrf_get (vrf_id, NULL);
b72ede27
FL
449 return vrf->info;
450}
451
452/* Look up the data pointer of the specified VRF. */
453void *
454vrf_info_lookup (vrf_id_t vrf_id)
455{
456 struct vrf *vrf = vrf_lookup (vrf_id);
457 return vrf ? vrf->info : NULL;
458}
459
8736158a
FL
460/* Look up the interface list in a VRF. */
461struct list *
462vrf_iflist (vrf_id_t vrf_id)
463{
464 struct vrf * vrf = vrf_lookup (vrf_id);
465 return vrf ? vrf->iflist : NULL;
466}
467
468/* Get the interface list of the specified VRF. Create one if not find. */
469struct list *
470vrf_iflist_get (vrf_id_t vrf_id)
471{
216b18ef 472 struct vrf * vrf = vrf_get (vrf_id, NULL);
8736158a
FL
473 return vrf->iflist;
474}
475
7076bb2f
FL
476/*
477 * VRF bit-map
478 */
479
480#define VRF_BITMAP_NUM_OF_GROUPS 8
481#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
482 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
483#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
484 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
485
486#define VRF_BITMAP_GROUP(_id) \
487 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
488#define VRF_BITMAP_BIT_OFFSET(_id) \
489 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
490
491#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
492 ((_bit_offset) / CHAR_BIT)
493#define VRF_BITMAP_FLAG(_bit_offset) \
494 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
495
496struct vrf_bitmap
497{
498 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
499};
500
501vrf_bitmap_t
502vrf_bitmap_init (void)
503{
504 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
505}
506
507void
508vrf_bitmap_free (vrf_bitmap_t bmap)
509{
510 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
511 int i;
512
513 if (bmap == VRF_BITMAP_NULL)
514 return;
515
516 for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
517 if (bm->groups[i])
518 XFREE (MTYPE_VRF_BITMAP, bm->groups[i]);
519
520 XFREE (MTYPE_VRF_BITMAP, bm);
521}
522
523void
524vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
525{
526 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
527 u_char group = VRF_BITMAP_GROUP (vrf_id);
528 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
529
530 if (bmap == VRF_BITMAP_NULL)
531 return;
532
533 if (bm->groups[group] == NULL)
534 bm->groups[group] = XCALLOC (MTYPE_VRF_BITMAP,
535 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
536
537 SET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
538 VRF_BITMAP_FLAG (offset));
539}
540
541void
542vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
543{
544 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
545 u_char group = VRF_BITMAP_GROUP (vrf_id);
546 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
547
548 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
549 return;
550
551 UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
552 VRF_BITMAP_FLAG (offset));
553}
554
555int
556vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
557{
558 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
559 u_char group = VRF_BITMAP_GROUP (vrf_id);
560 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
561
562 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
563 return 0;
564
565 return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
566 VRF_BITMAP_FLAG (offset)) ? 1 : 0;
567}
568
216b18ef
DS
569//Pending: See if combining the common parts with if_cmp_func() make sense.
570/* Compare interface names, returning an integer greater than, equal to, or
571 * less than 0, (following the strcmp convention), according to the
572 * relationship between vrfp1 and vrfp2. Interface names consist of an
573 * alphabetic prefix and a numeric suffix. The primary sort key is
574 * lexicographic by name, and then numeric by number. No number sorts
575 * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
576 * devpty0, de0 < del0
577 */
578int
579vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
580{
581 unsigned int l1, l2;
582 long int x1, x2;
583 char *p1, *p2;
584 int res;
585
586 p1 = vrfp1->name;
587 p2 = vrfp2->name;
588
589 while (*p1 && *p2) {
590 /* look up to any number */
591 l1 = strcspn(p1, "0123456789");
592 l2 = strcspn(p2, "0123456789");
593
594 /* name lengths are different -> compare names */
595 if (l1 != l2)
596 return (strcmp(p1, p2));
597
598 /* Note that this relies on all numbers being less than all letters, so
599 * that de0 < del0.
600 */
601 res = strncmp(p1, p2, l1);
602
603 /* names are different -> compare them */
604 if (res)
605 return res;
606
607 /* with identical name part, go to numeric part */
608 p1 += l1;
609 p2 += l1;
610
611 if (!*p1)
612 return -1;
613 if (!*p2)
614 return 1;
615
616 x1 = strtol(p1, &p1, 10);
617 x2 = strtol(p2, &p2, 10);
618
619 /* let's compare numbers now */
620 if (x1 < x2)
621 return -1;
622 if (x1 > x2)
623 return 1;
624
625 /* numbers were equal, lets do it again..
626 (it happens with name like "eth123.456:789") */
627 }
628 if (*p1)
629 return 1;
630 if (*p2)
631 return -1;
632 return 0;
633}
634
b72ede27
FL
635/* Initialize VRF module. */
636void
637vrf_init (void)
638{
639 struct vrf *default_vrf;
640
216b18ef
DS
641 vrf_list = list_new ();
642 vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
643
b72ede27
FL
644 /* Allocate VRF table. */
645 vrf_table = route_table_init ();
646
647 /* The default VRF always exists. */
216b18ef 648 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
b72ede27
FL
649 if (!default_vrf)
650 {
651 zlog_err ("vrf_init: failed to create the default VRF!");
652 exit (1);
653 }
654
e5bf3e1e
FL
655 /* Enable the default VRF. */
656 if (!vrf_enable (default_vrf))
657 {
658 zlog_err ("vrf_init: failed to enable the default VRF!");
659 exit (1);
660 }
b72ede27
FL
661}
662
663/* Terminate VRF module. */
664void
665vrf_terminate (void)
666{
667 struct route_node *rn;
668 struct vrf *vrf;
669
670 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
671 if ((vrf = rn->info) != NULL)
672 vrf_delete (vrf);
673
674 route_table_finish (vrf_table);
675 vrf_table = NULL;
676}
677
e5bf3e1e
FL
678/* Create a socket for the VRF. */
679int
680vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
681{
682 int ret = -1;
683
e5bf3e1e 684 ret = socket (domain, type, protocol);
e5bf3e1e
FL
685
686 return ret;
687}
688