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