]> git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
zebra/lib: move some code around
[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 /*
39 * Turn on/off debug code
40 * for vrf.
41 */
42 int debug_vrf = 0;
43
44 /* Holding VRF hooks */
45 struct vrf_master
46 {
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 **);
51 } vrf_master = {0,};
52
53 /* VRF table */
54 struct route_table *vrf_table = NULL;
55
56 /* VRF is part of a list too to store it before its actually active */
57 struct list *vrf_list;
58
59 static int vrf_is_enabled (struct vrf *vrf);
60 static void vrf_disable (struct vrf *vrf);
61
62 /* VRF list existance check by name. */
63 struct vrf *
64 vrf_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
78 /* Build the table key */
79 static void
80 vrf_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
87 /* Get a VRF. If not found, create one.
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
91 * Description: Please note that this routine can be called with just the name
92 * and 0 vrf-id
93 */
94 struct vrf *
95 vrf_get (vrf_id_t vrf_id, const char *name)
96 {
97 struct prefix p;
98 struct route_node *rn = NULL;
99 struct vrf *vrf = NULL;
100
101 if (debug_vrf)
102 zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
103
104 /*
105 * Nothing to see, move along here
106 */
107 if (!name && vrf_id == VRF_UNKNOWN)
108 return NULL;
109
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)
117 {
118 vrf = vrf_list_lookup_by_name (name);
119 if (vrf)
120 return vrf;
121
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)");
126 strcpy (vrf->name, name);
127 listnode_add_sort (vrf_list, vrf);
128 if_init (&vrf->iflist);
129 QOBJ_REG (vrf, vrf);
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;
140 }
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);
200
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);
218 QOBJ_REG (vrf, vrf);
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)
238 {
239 vrf_build_key (vrf_id, &p);
240 rn = route_node_get (vrf_table, &p);
241 if (debug_vrf)
242 zlog_debug("Vrf found: %p", rn->info);
243
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);
256 QOBJ_REG (vrf, vrf);
257 if (debug_vrf)
258 zlog_debug("Vrf Created: %p", vrf);
259 return vrf;
260 }
261 }
262
263 /*
264 * We shouldn't get here and if we do
265 * something has gone wrong.
266 */
267 return NULL;
268 }
269
270 /* Delete a VRF. This is called in vrf_terminate(). */
271 void
272 vrf_delete (struct vrf *vrf)
273 {
274 if (debug_vrf)
275 zlog_debug ("VRF %u is to be deleted.", vrf->vrf_id);
276
277 if (vrf_is_enabled (vrf))
278 vrf_disable (vrf);
279
280 if (vrf_master.vrf_delete_hook)
281 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
282
283 QOBJ_UNREG (vrf);
284 if_terminate (&vrf->iflist);
285
286 if (vrf->node)
287 {
288 vrf->node->info = NULL;
289 route_unlock_node(vrf->node);
290 }
291
292 listnode_delete (vrf_list, vrf);
293
294 XFREE (MTYPE_VRF, vrf);
295 }
296
297 /* Look up a VRF by identifier. */
298 struct vrf *
299 vrf_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
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 */
320 static int
321 vrf_is_enabled (struct vrf *vrf)
322 {
323 return vrf && CHECK_FLAG (vrf->status, VRF_ACTIVE);
324
325 /*Pending: figure out the real use of this routine.. it used to be..
326 return vrf && vrf->vrf_id == VRF_DEFAULT;
327 */
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 */
337 int
338 vrf_enable (struct vrf *vrf)
339 {
340 if (debug_vrf)
341 zlog_debug ("VRF %u is enabled.", vrf->vrf_id);
342
343 if (!CHECK_FLAG (vrf->status, VRF_ACTIVE))
344 SET_FLAG (vrf->status, VRF_ACTIVE);
345
346 if (vrf_master.vrf_enable_hook)
347 (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
348
349 return 1;
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 */
357 static void
358 vrf_disable (struct vrf *vrf)
359 {
360 if (vrf_is_enabled (vrf))
361 {
362 UNSET_FLAG (vrf->status, VRF_ACTIVE);
363
364 if (debug_vrf)
365 zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id);
366
367 /* Till now, nothing to be done for the default VRF. */
368 //Pending: see why this statement.
369
370 if (vrf_master.vrf_disable_hook)
371 (*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
372 }
373
374 }
375
376
377 /* Add a VRF hook. Please add hooks before calling vrf_init(). */
378 void
379 vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
380 {
381 if (debug_vrf)
382 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__,
383 type, func);
384
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;
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;
398 default:
399 break;
400 }
401 }
402
403 /* Return the iterator of the first VRF. */
404 vrf_iter_t
405 vrf_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. */
419 vrf_iter_t
420 vrf_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. */
439 vrf_iter_t
440 vrf_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. */
466 vrf_id_t
467 vrf_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
473 struct vrf *
474 vrf_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
480 /* Obtain the data pointer from the given VRF iterator. */
481 void *
482 vrf_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
488 /* Obtain the interface list from the given VRF iterator. */
489 struct list *
490 vrf_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
496 /* Look up a VRF by name. */
497 struct vrf *
498 vrf_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))
507 return vrf;
508 }
509
510 return NULL;
511 }
512
513 vrf_id_t
514 vrf_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
526 /* Get the data pointer of the specified VRF. If not found, create one. */
527 void *
528 vrf_info_get (vrf_id_t vrf_id)
529 {
530 struct vrf *vrf = vrf_get (vrf_id, NULL);
531 return vrf->info;
532 }
533
534 /* Look up the data pointer of the specified VRF. */
535 void *
536 vrf_info_lookup (vrf_id_t vrf_id)
537 {
538 struct vrf *vrf = vrf_lookup (vrf_id);
539 return vrf ? vrf->info : NULL;
540 }
541
542 /* Look up the interface list in a VRF. */
543 struct list *
544 vrf_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. */
551 struct list *
552 vrf_iflist_get (vrf_id_t vrf_id)
553 {
554 struct vrf * vrf = vrf_get (vrf_id, NULL);
555 return vrf->iflist;
556 }
557
558 /* Create the interface list for the specified VRF, if needed. */
559 void
560 vrf_iflist_create (vrf_id_t vrf_id)
561 {
562 struct vrf * vrf = vrf_lookup (vrf_id);
563 if (vrf && !vrf->iflist)
564 if_init (&vrf->iflist);
565 }
566
567 /* Free the interface list of the specified VRF. */
568 void
569 vrf_iflist_terminate (vrf_id_t vrf_id)
570 {
571 struct vrf * vrf = vrf_lookup (vrf_id);
572 if (vrf && vrf->iflist)
573 if_terminate (&vrf->iflist);
574 }
575
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
596 struct vrf_bitmap
597 {
598 u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
599 };
600
601 vrf_bitmap_t
602 vrf_bitmap_init (void)
603 {
604 return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
605 }
606
607 void
608 vrf_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
623 void
624 vrf_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
641 void
642 vrf_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
655 int
656 vrf_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
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 */
677 static int
678 vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
679 {
680 return if_cmp_name_func (vrfp1->name, vrfp2->name);
681 }
682
683 /* Initialize VRF module. */
684 void
685 vrf_init (void)
686 {
687 struct vrf *default_vrf;
688
689 if (debug_vrf)
690 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__);
691
692 vrf_list = list_new ();
693 vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
694
695 /* Allocate VRF table. */
696 vrf_table = route_table_init ();
697
698 /* The default VRF always exists. */
699 default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
700 if (!default_vrf)
701 {
702 zlog_err ("vrf_init: failed to create the default VRF!");
703 exit (1);
704 }
705
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 }
712 }
713
714 /* Terminate VRF module. */
715 void
716 vrf_terminate (void)
717 {
718 struct route_node *rn;
719 struct vrf *vrf;
720
721 if (debug_vrf)
722 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
723
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
732 /* Create a socket for the VRF. */
733 int
734 vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
735 {
736 int ret = -1;
737
738 ret = socket (domain, type, protocol);
739
740 return ret;
741 }
742
743 /* vrf CLI commands */
744 DEFUN (vrf,
745 vrf_cmd,
746 "vrf NAME",
747 "Select a VRF to configure\n"
748 "VRF's name\n")
749 {
750 struct vrf *vrfp;
751 size_t sl;
752
753 if ((sl = strlen(argv[0])) > VRF_NAMSIZ)
754 {
755 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
756 "%d characters%s",
757 argv[0], VRF_NAMSIZ, VTY_NEWLINE);
758 return CMD_WARNING;
759 }
760
761 vrfp = vrf_get (VRF_UNKNOWN, argv[0]);
762
763 VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp);
764
765 return CMD_SUCCESS;
766 }
767
768 DEFUN_NOSH (no_vrf,
769 no_vrf_cmd,
770 "no vrf NAME",
771 NO_STR
772 "Delete a pseudo VRF's configuration\n"
773 "VRF's name\n")
774 {
775 struct vrf *vrfp;
776
777 vrfp = vrf_list_lookup_by_name (argv[0]);
778
779 if (vrfp == NULL)
780 {
781 vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE);
782 return CMD_WARNING;
783 }
784
785 if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
786 {
787 vty_out (vty, "%% Only inactive VRFs can be deleted%s",
788 VTY_NEWLINE);
789 return CMD_WARNING;
790 }
791
792 vrf_delete(vrfp);
793
794 return CMD_SUCCESS;
795 }
796
797 /*
798 * Debug CLI for vrf's
799 */
800 DEFUN (vrf_debug,
801 vrf_debug_cmd,
802 "debug vrf",
803 DEBUG_STR
804 "VRF Debugging\n")
805 {
806 debug_vrf = 1;
807
808 return CMD_SUCCESS;
809 }
810
811 DEFUN (no_vrf_debug,
812 no_vrf_debug_cmd,
813 "no debug vrf",
814 NO_STR
815 DEBUG_STR
816 "VRF Debugging\n")
817 {
818 debug_vrf = 0;
819
820 return CMD_SUCCESS;
821 }
822
823 static int
824 vrf_write_host (struct vty *vty)
825 {
826 if (debug_vrf)
827 vty_out (vty, "debug vrf%s", VTY_NEWLINE);
828
829 return 1;
830 }
831
832 static struct cmd_node vrf_debug_node =
833 {
834 VRF_DEBUG_NODE,
835 "",
836 1
837 };
838
839 void
840 vrf_install_commands (void)
841 {
842 install_node (&vrf_debug_node, vrf_write_host);
843
844 install_element (CONFIG_NODE, &vrf_debug_cmd);
845 install_element (ENABLE_NODE, &vrf_debug_cmd);
846 install_element (CONFIG_NODE, &no_vrf_debug_cmd);
847 install_element (ENABLE_NODE, &no_vrf_debug_cmd);
848 }