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