]> git.proxmox.com Git - mirror_frr.git/blame - lib/vrf.c
zebra: fix show ip route vrf to use zvrf_list
[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
33/*
34 * Turn on/off debug code
35 * for vrf.
36 */
37int debug_vrf = 0;
b72ede27 38
b72ede27
FL
39/* Holding VRF hooks */
40struct vrf_master
41{
216b18ef
DS
42 int (*vrf_new_hook) (vrf_id_t, const char *, void **);
43 int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
44 int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
45 int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
b72ede27
FL
46} vrf_master = {0,};
47
48/* VRF table */
49struct route_table *vrf_table = NULL;
50
216b18ef
DS
51/* VRF is part of a list too to store it before its actually active */
52struct list *vrf_list;
53
e5bf3e1e 54static int vrf_is_enabled (struct vrf *vrf);
e5bf3e1e
FL
55static void vrf_disable (struct vrf *vrf);
56
216b18ef
DS
57/* VRF list existance check by name. */
58struct vrf *
59vrf_list_lookup_by_name (const char *name)
60{
61 struct listnode *node;
62 struct vrf *vrfp;
63
64 if (name)
65 for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
66 {
67 if (strcmp(name, vrfp->name) == 0)
68 return vrfp;
69 }
70 return NULL;
71}
72
b72ede27
FL
73/* Build the table key */
74static void
75vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
76{
77 p->family = AF_INET;
78 p->prefixlen = IPV4_MAX_BITLEN;
79 p->u.prefix4.s_addr = vrf_id;
80}
81
216b18ef 82/* Get a VRF. If not found, create one.
34f8e6af
DS
83 * Arg:
84 * name - The name of the vrf. May be NULL if unknown.
85 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
216b18ef 86 * Description: Please note that this routine can be called with just the name
34f8e6af
DS
87 * and 0 vrf-id
88 */
216b18ef
DS
89struct vrf *
90vrf_get (vrf_id_t vrf_id, const char *name)
b72ede27
FL
91{
92 struct prefix p;
c88a8b75 93 struct route_node *rn = NULL;
216b18ef 94 struct vrf *vrf = NULL;
216b18ef 95
34f8e6af
DS
96 if (debug_vrf)
97 zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
c88a8b75 98
34f8e6af
DS
99 /*
100 * Nothing to see, move along here
101 */
102 if (!name && vrf_id == VRF_UNKNOWN)
103 return NULL;
c88a8b75 104
34f8e6af
DS
105 /*
106 * Valid vrf name and unknown vrf_id case
107 *
108 * This is called when we are configured from
109 * the cli but we have no kernel information yet.
110 */
111 if (name && vrf_id == VRF_UNKNOWN)
c88a8b75 112 {
34f8e6af
DS
113 vrf = vrf_list_lookup_by_name (name);
114 if (vrf)
115 return vrf;
8087b296 116
c88a8b75
DS
117 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
118 if (debug_vrf)
119 zlog_debug ("VRF(%u) %s is created.",
120 vrf_id, (name) ? name : "(NULL)");
34f8e6af
DS
121 strcpy (vrf->name, name);
122 listnode_add_sort (vrf_list, vrf);
b2d7c082 123 if_init (&vrf->iflist);
34f8e6af
DS
124 if (vrf_master.vrf_new_hook)
125 {
126 (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
127
128 if (debug_vrf && vrf->info)
129 zlog_info ("zvrf is created.");
130 }
131 if (debug_vrf)
132 zlog_debug("Vrf Created: %p", vrf);
133 return vrf;
216b18ef 134 }
34f8e6af
DS
135 /*
136 * Valid vrf name and valid vrf_id case
137 *
138 * This can be passed from the kernel
139 */
140 else if (name && vrf_id != VRF_UNKNOWN)
141 {
142 vrf = vrf_list_lookup_by_name (name);
143 if (vrf)
144 {
145 /*
146 * If the passed in vrf_id and name match
147 * return, nothing to do here.
148 */
149 if (vrf->vrf_id == vrf_id)
150 return vrf;
151
152 /*
153 * Now we have a situation where we've had a
154 * vrf created, but not yet created the vrf_id route
155 * node, let's do so and match the code up.
156 */
157 vrf_build_key (vrf_id, &p);
158 rn = route_node_get (vrf_table, &p);
159
160 rn->info = vrf;
161 vrf->node = rn;
162 vrf->vrf_id = vrf_id;
163 if (vrf_master.vrf_new_hook)
164 (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
165
166 if (debug_vrf)
167 zlog_debug("Vrf found matched stuff up: %p", vrf);
168
169 return vrf;
170 }
171 else
172 {
173 /*
174 * We can have 1 of two situations here
175 * We've already been told about the vrf_id
176 * or we haven't.
177 */
178 vrf_build_key (vrf_id, &p);
179 rn = route_node_get (vrf_table, &p);
180 if (rn->info)
181 {
182 vrf = rn->info;
183 route_unlock_node (rn);
184 /*
185 * We know at this point that the vrf->name is not
186 * right because we would have caught it above.
187 * so let's set it.
188 */
189 strcpy (vrf->name, name);
190 listnode_add_sort (vrf_list, vrf);
191 if (vrf_master.vrf_new_hook)
192 {
193 (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
b72ede27 194
34f8e6af
DS
195 if (debug_vrf && vrf->info)
196 zlog_info ("zvrf is created.");
197 }
198 if (debug_vrf)
199 zlog_debug("Vrf Created: %p", vrf);
200 return vrf;
201 }
202 else
203 {
204 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
205
206 rn->info = vrf;
207 vrf->node = rn;
208 vrf->vrf_id = vrf_id;
209 strcpy (vrf->name, name);
210 listnode_add_sort (vrf_list, vrf);
211 if_init (&vrf->iflist);
212 if (vrf_master.vrf_new_hook)
213 {
214 (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
215
216 if (debug_vrf && vrf->info)
217 zlog_info ("zvrf is created.");
218 }
219 if (debug_vrf)
220 zlog_debug("Vrf Created: %p", vrf);
221 return vrf;
222 }
223 }
224 }
225 /*
226 * The final case, we've been passed a valid vrf_id
227 * but no name. So we create the route node
228 * if it hasn't already been created.
229 */
230 else if (!name)
c88a8b75 231 {
34f8e6af
DS
232 vrf_build_key (vrf_id, &p);
233 rn = route_node_get (vrf_table, &p);
0b6d694b
DS
234 if (debug_vrf)
235 zlog_debug("Vrf found: %p", rn->info);
c88a8b75 236
34f8e6af
DS
237 if (rn->info)
238 {
239 route_unlock_node (rn);
240 return (rn->info);
241 }
242 else
243 {
244 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
245 rn->info = vrf;
246 vrf->node = rn;
247 vrf->vrf_id = vrf_id;
248 if_init (&vrf->iflist);
249 if (debug_vrf)
250 zlog_debug("Vrf Created: %p", vrf);
251 return vrf;
252 }
c88a8b75 253 }
216b18ef 254
34f8e6af
DS
255 /*
256 * We shouldn't get here and if we do
257 * something has gone wrong.
258 */
259 return NULL;
b72ede27
FL
260}
261
262/* Delete a VRF. This is called in vrf_terminate(). */
216b18ef 263void
b72ede27
FL
264vrf_delete (struct vrf *vrf)
265{
19dc275e
DS
266 if (debug_vrf)
267 zlog_debug ("VRF %u is to be deleted.", vrf->vrf_id);
b72ede27 268
e5bf3e1e
FL
269 if (vrf_is_enabled (vrf))
270 vrf_disable (vrf);
271
b72ede27 272 if (vrf_master.vrf_delete_hook)
216b18ef
DS
273 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
274
79694123 275 if (CHECK_FLAG (vrf->status, VRF_ACTIVE))
b2d7c082 276 if_terminate (&vrf->iflist);
b72ede27 277
216b18ef
DS
278 if (vrf->node)
279 {
280 vrf->node->info = NULL;
281 route_unlock_node(vrf->node);
282 }
8736158a 283
216b18ef 284 listnode_delete (vrf_list, vrf);
b72ede27
FL
285
286 XFREE (MTYPE_VRF, vrf);
287}
288
289/* Look up a VRF by identifier. */
216b18ef 290struct vrf *
b72ede27
FL
291vrf_lookup (vrf_id_t vrf_id)
292{
293 struct prefix p;
294 struct route_node *rn;
295 struct vrf *vrf = NULL;
296
297 vrf_build_key (vrf_id, &p);
298 rn = route_node_lookup (vrf_table, &p);
299 if (rn)
300 {
301 vrf = (struct vrf *)rn->info;
302 route_unlock_node (rn); /* lookup */
303 }
304 return vrf;
305}
306
e5bf3e1e
FL
307/*
308 * Check whether the VRF is enabled - that is, whether the VRF
309 * is ready to allocate resources. Currently there's only one
310 * type of resource: socket.
311 */
312static int
313vrf_is_enabled (struct vrf *vrf)
314{
79694123 315 return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
216b18ef
DS
316
317 /*Pending: figure out the real use of this routine.. it used to be..
e5bf3e1e 318 return vrf && vrf->vrf_id == VRF_DEFAULT;
216b18ef 319 */
e5bf3e1e
FL
320}
321
322/*
323 * Enable a VRF - that is, let the VRF be ready to use.
324 * The VRF_ENABLE_HOOK callback will be called to inform
325 * that they can allocate resources in this VRF.
326 *
327 * RETURN: 1 - enabled successfully; otherwise, 0.
328 */
216b18ef 329int
e5bf3e1e
FL
330vrf_enable (struct vrf *vrf)
331{
19dc275e
DS
332 if (debug_vrf)
333 zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
e5bf3e1e 334
e2b1be64
DS
335 if (!CHECK_FLAG (vrf->status, VRF_ACTIVE))
336 SET_FLAG (vrf->status, VRF_ACTIVE);
e5bf3e1e 337
e2b1be64
DS
338 if (vrf_master.vrf_enable_hook)
339 (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
e5bf3e1e 340
e2b1be64 341 return 1;
e5bf3e1e
FL
342}
343
344/*
345 * Disable a VRF - that is, let the VRF be unusable.
346 * The VRF_DELETE_HOOK callback will be called to inform
347 * that they must release the resources in the VRF.
348 */
349static void
350vrf_disable (struct vrf *vrf)
351{
e74f14fc 352 UNSET_FLAG (vrf->status, VRF_ACTIVE);
e5bf3e1e
FL
353 if (vrf_is_enabled (vrf))
354 {
19dc275e
DS
355 if (debug_vrf)
356 zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
e5bf3e1e
FL
357
358 /* Till now, nothing to be done for the default VRF. */
216b18ef 359 //Pending: see why this statement.
e5bf3e1e
FL
360
361 if (vrf_master.vrf_disable_hook)
216b18ef 362 (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
e5bf3e1e 363 }
e74f14fc 364
e5bf3e1e
FL
365}
366
367
b72ede27
FL
368/* Add a VRF hook. Please add hooks before calling vrf_init(). */
369void
216b18ef 370vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
b72ede27 371{
19dc275e
DS
372 if (debug_vrf)
373 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
374 type, func);
375
b72ede27
FL
376 switch (type) {
377 case VRF_NEW_HOOK:
378 vrf_master.vrf_new_hook = func;
379 break;
380 case VRF_DELETE_HOOK:
381 vrf_master.vrf_delete_hook = func;
382 break;
e5bf3e1e
FL
383 case VRF_ENABLE_HOOK:
384 vrf_master.vrf_enable_hook = func;
385 break;
386 case VRF_DISABLE_HOOK:
387 vrf_master.vrf_disable_hook = func;
388 break;
b72ede27
FL
389 default:
390 break;
391 }
392}
393
394/* Return the iterator of the first VRF. */
395vrf_iter_t
396vrf_first (void)
397{
398 struct route_node *rn;
399
400 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
401 if (rn->info)
402 {
403 route_unlock_node (rn); /* top/next */
404 return (vrf_iter_t)rn;
405 }
406 return VRF_ITER_INVALID;
407}
408
409/* Return the next VRF iterator to the given iterator. */
410vrf_iter_t
411vrf_next (vrf_iter_t iter)
412{
413 struct route_node *rn = NULL;
414
415 /* Lock it first because route_next() will unlock it. */
416 if (iter != VRF_ITER_INVALID)
417 rn = route_next (route_lock_node ((struct route_node *)iter));
418
419 for (; rn; rn = route_next (rn))
420 if (rn->info)
421 {
422 route_unlock_node (rn); /* next */
423 return (vrf_iter_t)rn;
424 }
425 return VRF_ITER_INVALID;
426}
427
428/* Return the VRF iterator of the given VRF ID. If it does not exist,
429 * the iterator of the next existing VRF is returned. */
430vrf_iter_t
431vrf_iterator (vrf_id_t vrf_id)
432{
433 struct prefix p;
434 struct route_node *rn;
435
436 vrf_build_key (vrf_id, &p);
437 rn = route_node_get (vrf_table, &p);
438 if (rn->info)
439 {
440 /* OK, the VRF exists. */
441 route_unlock_node (rn); /* get */
442 return (vrf_iter_t)rn;
443 }
444
445 /* Find the next VRF. */
446 for (rn = route_next (rn); rn; rn = route_next (rn))
447 if (rn->info)
448 {
449 route_unlock_node (rn); /* next */
450 return (vrf_iter_t)rn;
451 }
452
453 return VRF_ITER_INVALID;
454}
455
456/* Obtain the VRF ID from the given VRF iterator. */
457vrf_id_t
458vrf_iter2id (vrf_iter_t iter)
459{
460 struct route_node *rn = (struct route_node *) iter;
461 return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
462}
463
216b18ef
DS
464struct vrf *
465vrf_iter2vrf (vrf_iter_t iter)
466{
467 struct route_node *rn = (struct route_node *) iter;
468 return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
469}
470
b72ede27
FL
471/* Obtain the data pointer from the given VRF iterator. */
472void *
473vrf_iter2info (vrf_iter_t iter)
474{
475 struct route_node *rn = (struct route_node *) iter;
476 return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
477}
478
8736158a
FL
479/* Obtain the interface list from the given VRF iterator. */
480struct list *
481vrf_iter2iflist (vrf_iter_t iter)
482{
483 struct route_node *rn = (struct route_node *) iter;
484 return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
485}
486
216b18ef
DS
487/* Look up a VRF by name. */
488struct vrf *
489vrf_lookup_by_name (const char *name)
490{
491 struct vrf *vrf = NULL;
492 vrf_iter_t iter;
493
494 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
495 {
496 vrf = vrf_iter2vrf (iter);
497 if (vrf && !strcmp(vrf->name, name))
2e447c86 498 return vrf;
216b18ef
DS
499 }
500
2e447c86 501 return NULL;
216b18ef
DS
502}
503
504vrf_id_t
505vrf_name_to_id (const char *name)
506{
507 struct vrf *vrf;
508 vrf_id_t vrf_id = VRF_DEFAULT; //Pending: need a way to return invalid id/ routine not used.
509
510 vrf = vrf_lookup_by_name (name);
511 if (vrf)
512 vrf_id = vrf->vrf_id;
513
514 return vrf_id;
515}
516
b72ede27
FL
517/* Get the data pointer of the specified VRF. If not found, create one. */
518void *
519vrf_info_get (vrf_id_t vrf_id)
520{
216b18ef 521 struct vrf *vrf = vrf_get (vrf_id, NULL);
b72ede27
FL
522 return vrf->info;
523}
524
525/* Look up the data pointer of the specified VRF. */
526void *
527vrf_info_lookup (vrf_id_t vrf_id)
528{
529 struct vrf *vrf = vrf_lookup (vrf_id);
530 return vrf ? vrf->info : NULL;
531}
532
8736158a
FL
533/* Look up the interface list in a VRF. */
534struct list *
535vrf_iflist (vrf_id_t vrf_id)
536{
537 struct vrf * vrf = vrf_lookup (vrf_id);
538 return vrf ? vrf->iflist : NULL;
539}
540
541/* Get the interface list of the specified VRF. Create one if not find. */
542struct list *
543vrf_iflist_get (vrf_id_t vrf_id)
544{
216b18ef 545 struct vrf * vrf = vrf_get (vrf_id, NULL);
8736158a
FL
546 return vrf->iflist;
547}
548
b33adb7c 549/* Create the interface list for the specified VRF, if needed. */
550void
551vrf_iflist_create (vrf_id_t vrf_id)
552{
553 struct vrf * vrf = vrf_lookup (vrf_id);
554 if (vrf && !vrf->iflist)
b2d7c082 555 if_init (&vrf->iflist);
b33adb7c 556}
557
009b18fc 558/* Free the interface list of the specified VRF. */
559void
560vrf_iflist_terminate (vrf_id_t vrf_id)
561{
562 struct vrf * vrf = vrf_lookup (vrf_id);
563 if (vrf && vrf->iflist)
b2d7c082 564 if_terminate (&vrf->iflist);
009b18fc 565}
566
7076bb2f
FL
567/*
568 * VRF bit-map
569 */
570
571#define VRF_BITMAP_NUM_OF_GROUPS 8
572#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
573 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
574#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
575 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
576
577#define VRF_BITMAP_GROUP(_id) \
578 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
579#define VRF_BITMAP_BIT_OFFSET(_id) \
580 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
581
582#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
583 ((_bit_offset) / CHAR_BIT)
584#define VRF_BITMAP_FLAG(_bit_offset) \
585 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
586
587struct vrf_bitmap
588{
589 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
590};
591
592vrf_bitmap_t
593vrf_bitmap_init (void)
594{
595 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
596}
597
598void
599vrf_bitmap_free (vrf_bitmap_t bmap)
600{
601 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
602 int i;
603
604 if (bmap == VRF_BITMAP_NULL)
605 return;
606
607 for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
608 if (bm->groups[i])
609 XFREE (MTYPE_VRF_BITMAP, bm->groups[i]);
610
611 XFREE (MTYPE_VRF_BITMAP, bm);
612}
613
614void
615vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
616{
617 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
618 u_char group = VRF_BITMAP_GROUP (vrf_id);
619 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
620
621 if (bmap == VRF_BITMAP_NULL)
622 return;
623
624 if (bm->groups[group] == NULL)
625 bm->groups[group] = XCALLOC (MTYPE_VRF_BITMAP,
626 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
627
628 SET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
629 VRF_BITMAP_FLAG (offset));
630}
631
632void
633vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
634{
635 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
636 u_char group = VRF_BITMAP_GROUP (vrf_id);
637 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
638
639 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
640 return;
641
642 UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
643 VRF_BITMAP_FLAG (offset));
644}
645
646int
647vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
648{
649 struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
650 u_char group = VRF_BITMAP_GROUP (vrf_id);
651 u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
652
653 if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
654 return 0;
655
656 return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
657 VRF_BITMAP_FLAG (offset)) ? 1 : 0;
658}
659
216b18ef
DS
660/* Compare interface names, returning an integer greater than, equal to, or
661 * less than 0, (following the strcmp convention), according to the
662 * relationship between vrfp1 and vrfp2. Interface names consist of an
663 * alphabetic prefix and a numeric suffix. The primary sort key is
664 * lexicographic by name, and then numeric by number. No number sorts
665 * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
666 * devpty0, de0 < del0
667 */
974fc9d2 668static int
216b18ef
DS
669vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
670{
974fc9d2 671 return if_cmp_name_func (vrfp1->name, vrfp2->name);
216b18ef
DS
672}
673
b72ede27
FL
674/* Initialize VRF module. */
675void
676vrf_init (void)
677{
678 struct vrf *default_vrf;
679
19dc275e
DS
680 if (debug_vrf)
681 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
682
216b18ef
DS
683 vrf_list = list_new ();
684 vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
685
b72ede27
FL
686 /* Allocate VRF table. */
687 vrf_table = route_table_init ();
688
689 /* The default VRF always exists. */
216b18ef 690 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
b72ede27
FL
691 if (!default_vrf)
692 {
693 zlog_err ("vrf_init: failed to create the default VRF!");
694 exit (1);
695 }
696
e5bf3e1e
FL
697 /* Enable the default VRF. */
698 if (!vrf_enable (default_vrf))
699 {
700 zlog_err ("vrf_init: failed to enable the default VRF!");
701 exit (1);
702 }
b72ede27
FL
703}
704
705/* Terminate VRF module. */
706void
707vrf_terminate (void)
708{
709 struct route_node *rn;
710 struct vrf *vrf;
711
19dc275e
DS
712 if (debug_vrf)
713 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
714
b72ede27
FL
715 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
716 if ((vrf = rn->info) != NULL)
717 vrf_delete (vrf);
718
719 route_table_finish (vrf_table);
720 vrf_table = NULL;
721}
722
e5bf3e1e
FL
723/* Create a socket for the VRF. */
724int
725vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
726{
727 int ret = -1;
728
19dc275e 729 ret = socket (domain, type, protocol);
e5bf3e1e
FL
730
731 return ret;
732}
733
19dc275e
DS
734/*
735 * Debug CLI for vrf's
736 */
737DEFUN (vrf_debug,
738 vrf_debug_cmd,
739 "debug vrf",
740 DEBUG_STR
741 "VRF Debugging\n")
742{
743 debug_vrf = 1;
744
745 return CMD_SUCCESS;
746}
747
748DEFUN (no_vrf_debug,
749 no_vrf_debug_cmd,
750 "no debug vrf",
751 NO_STR
752 DEBUG_STR
753 "VRF Debugging\n")
754{
755 debug_vrf = 0;
756
757 return CMD_SUCCESS;
758}
759
760static int
761vrf_write_host (struct vty *vty)
762{
763 if (debug_vrf)
764 vty_out (vty, "debug vrf%s", VTY_NEWLINE);
765
766 return 1;
767}
768
769static struct cmd_node vrf_debug_node =
770{
771 VRF_DEBUG_NODE,
772 "",
773 1
774};
775
776void
777vrf_install_commands (void)
778{
779 install_node (&vrf_debug_node, vrf_write_host);
780
781 install_element (CONFIG_NODE, &vrf_debug_cmd);
782 install_element (ENABLE_NODE, &vrf_debug_cmd);
783 install_element (CONFIG_NODE, &no_vrf_debug_cmd);
784 install_element (ENABLE_NODE, &no_vrf_debug_cmd);
785}