3 * Copyright (C) 2014 6WIND S.A.
5 * This file is part of GNU Zebra.
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.
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.
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.
33 DEFINE_MTYPE_STATIC(LIB
, VRF
, "VRF")
34 DEFINE_MTYPE_STATIC(LIB
, VRF_BITMAP
, "VRF bit-map")
38 static __inline
int vrf_id_compare (struct vrf
*, struct vrf
*);
39 static __inline
int vrf_name_compare (struct vrf
*, struct vrf
*);
41 RB_GENERATE (vrf_id_head
, vrf
, id_entry
, vrf_id_compare
)
42 RB_GENERATE (vrf_name_head
, vrf
, name_entry
, vrf_name_compare
)
44 struct vrf_id_head vrfs_by_id
= RB_INITIALIZER (&vrfs_by_id
);
45 struct vrf_name_head vrfs_by_name
= RB_INITIALIZER (&vrfs_by_name
);
48 * Turn on/off debug code
53 /* Holding VRF hooks */
56 int (*vrf_new_hook
) (struct vrf
*);
57 int (*vrf_delete_hook
) (struct vrf
*);
58 int (*vrf_enable_hook
) (struct vrf
*);
59 int (*vrf_disable_hook
) (struct vrf
*);
62 static int vrf_is_enabled (struct vrf
*vrf
);
63 static void vrf_disable (struct vrf
*vrf
);
65 /* VRF list existance check by name. */
67 vrf_lookup_by_name (const char *name
)
70 strlcpy (vrf
.name
, name
, sizeof (vrf
.name
));
71 return (RB_FIND (vrf_name_head
, &vrfs_by_name
, &vrf
));
75 vrf_id_compare (struct vrf
*a
, struct vrf
*b
)
77 return (a
->vrf_id
- b
->vrf_id
);
81 vrf_name_compare (struct vrf
*a
, struct vrf
*b
)
83 return strcmp (a
->name
, b
->name
);
86 /* Get a VRF. If not found, create one.
88 * name - The name of the vrf. May be NULL if unknown.
89 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
90 * Description: Please note that this routine can be called with just the name
94 vrf_get (vrf_id_t vrf_id
, const char *name
)
96 struct vrf
*vrf
= NULL
;
100 zlog_debug ("VRF_GET: %s(%d)", name
, vrf_id
);
102 /* Nothing to see, move along here */
103 if (!name
&& vrf_id
== VRF_UNKNOWN
)
106 /* Try to find VRF both by ID and name */
107 if (vrf_id
!= VRF_UNKNOWN
)
108 vrf
= vrf_lookup_by_id (vrf_id
);
110 vrf
= vrf_lookup_by_name (name
);
114 vrf
= XCALLOC (MTYPE_VRF
, sizeof (struct vrf
));
115 vrf
->vrf_id
= VRF_UNKNOWN
;
116 if_init (&vrf
->iflist
);
121 zlog_debug ("VRF(%u) %s is created.",
122 vrf_id
, (name
) ? name
: "(NULL)");
126 if (vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
== VRF_UNKNOWN
)
128 vrf
->vrf_id
= vrf_id
;
129 RB_INSERT (vrf_id_head
, &vrfs_by_id
, vrf
);
133 if (name
&& vrf
->name
[0] != '\0' && strcmp (name
, vrf
->name
))
135 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
136 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
137 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
139 else if (name
&& vrf
->name
[0] == '\0')
141 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
142 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
145 if (new && vrf_master
.vrf_new_hook
)
146 (*vrf_master
.vrf_new_hook
) (vrf
);
151 /* Delete a VRF. This is called in vrf_terminate(). */
153 vrf_delete (struct vrf
*vrf
)
156 zlog_debug ("VRF %u is to be deleted.", vrf
->vrf_id
);
158 if (vrf_is_enabled (vrf
))
161 if (vrf_master
.vrf_delete_hook
)
162 (*vrf_master
.vrf_delete_hook
) (vrf
);
165 if_terminate (&vrf
->iflist
);
167 if (vrf
->vrf_id
!= VRF_UNKNOWN
)
168 RB_REMOVE (vrf_id_head
, &vrfs_by_id
, vrf
);
169 if (vrf
->name
[0] != '\0')
170 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
172 XFREE (MTYPE_VRF
, vrf
);
175 /* Look up a VRF by identifier. */
177 vrf_lookup_by_id (vrf_id_t vrf_id
)
181 return (RB_FIND (vrf_id_head
, &vrfs_by_id
, &vrf
));
185 * Check whether the VRF is enabled.
188 vrf_is_enabled (struct vrf
*vrf
)
190 return vrf
&& CHECK_FLAG (vrf
->status
, VRF_ACTIVE
);
194 * Enable a VRF - that is, let the VRF be ready to use.
195 * The VRF_ENABLE_HOOK callback will be called to inform
196 * that they can allocate resources in this VRF.
198 * RETURN: 1 - enabled successfully; otherwise, 0.
201 vrf_enable (struct vrf
*vrf
)
203 if (vrf_is_enabled (vrf
))
207 zlog_debug ("VRF %u is enabled.", vrf
->vrf_id
);
209 SET_FLAG (vrf
->status
, VRF_ACTIVE
);
211 if (vrf_master
.vrf_enable_hook
)
212 (*vrf_master
.vrf_enable_hook
) (vrf
);
218 * Disable a VRF - that is, let the VRF be unusable.
219 * The VRF_DELETE_HOOK callback will be called to inform
220 * that they must release the resources in the VRF.
223 vrf_disable (struct vrf
*vrf
)
225 if (! vrf_is_enabled (vrf
))
228 UNSET_FLAG (vrf
->status
, VRF_ACTIVE
);
231 zlog_debug ("VRF %u is to be disabled.", vrf
->vrf_id
);
233 /* Till now, nothing to be done for the default VRF. */
234 //Pending: see why this statement.
236 if (vrf_master
.vrf_disable_hook
)
237 (*vrf_master
.vrf_disable_hook
) (vrf
);
241 /* Add a VRF hook. Please add hooks before calling vrf_init(). */
243 vrf_add_hook (int type
, int (*func
)(struct vrf
*))
246 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__
,
251 vrf_master
.vrf_new_hook
= func
;
253 case VRF_DELETE_HOOK
:
254 vrf_master
.vrf_delete_hook
= func
;
256 case VRF_ENABLE_HOOK
:
257 vrf_master
.vrf_enable_hook
= func
;
259 case VRF_DISABLE_HOOK
:
260 vrf_master
.vrf_disable_hook
= func
;
268 vrf_name_to_id (const char *name
)
271 vrf_id_t vrf_id
= VRF_DEFAULT
; //Pending: need a way to return invalid id/ routine not used.
273 vrf
= vrf_lookup_by_name (name
);
275 vrf_id
= vrf
->vrf_id
;
280 /* Get the data pointer of the specified VRF. If not found, create one. */
282 vrf_info_get (vrf_id_t vrf_id
)
284 struct vrf
*vrf
= vrf_get (vrf_id
, NULL
);
288 /* Look up the data pointer of the specified VRF. */
290 vrf_info_lookup (vrf_id_t vrf_id
)
292 struct vrf
*vrf
= vrf_lookup_by_id (vrf_id
);
293 return vrf
? vrf
->info
: NULL
;
296 /* Look up the interface list in a VRF. */
298 vrf_iflist (vrf_id_t vrf_id
)
300 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
301 return vrf
? vrf
->iflist
: NULL
;
304 /* Get the interface list of the specified VRF. Create one if not find. */
306 vrf_iflist_get (vrf_id_t vrf_id
)
308 struct vrf
* vrf
= vrf_get (vrf_id
, NULL
);
312 /* Create the interface list for the specified VRF, if needed. */
314 vrf_iflist_create (vrf_id_t vrf_id
)
316 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
317 if (vrf
&& !vrf
->iflist
)
318 if_init (&vrf
->iflist
);
321 /* Free the interface list of the specified VRF. */
323 vrf_iflist_terminate (vrf_id_t vrf_id
)
325 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
326 if (vrf
&& vrf
->iflist
)
327 if_terminate (&vrf
->iflist
);
334 #define VRF_BITMAP_NUM_OF_GROUPS 8
335 #define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
336 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
337 #define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
338 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
340 #define VRF_BITMAP_GROUP(_id) \
341 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
342 #define VRF_BITMAP_BIT_OFFSET(_id) \
343 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
345 #define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
346 ((_bit_offset) / CHAR_BIT)
347 #define VRF_BITMAP_FLAG(_bit_offset) \
348 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
352 u_char
*groups
[VRF_BITMAP_NUM_OF_GROUPS
];
356 vrf_bitmap_init (void)
358 return (vrf_bitmap_t
) XCALLOC (MTYPE_VRF_BITMAP
, sizeof (struct vrf_bitmap
));
362 vrf_bitmap_free (vrf_bitmap_t bmap
)
364 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
367 if (bmap
== VRF_BITMAP_NULL
)
370 for (i
= 0; i
< VRF_BITMAP_NUM_OF_GROUPS
; i
++)
372 XFREE (MTYPE_VRF_BITMAP
, bm
->groups
[i
]);
374 XFREE (MTYPE_VRF_BITMAP
, bm
);
378 vrf_bitmap_set (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
380 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
381 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
382 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
384 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
)
387 if (bm
->groups
[group
] == NULL
)
388 bm
->groups
[group
] = XCALLOC (MTYPE_VRF_BITMAP
,
389 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP
);
391 SET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
392 VRF_BITMAP_FLAG (offset
));
396 vrf_bitmap_unset (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
398 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
399 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
400 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
402 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
403 bm
->groups
[group
] == NULL
)
406 UNSET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
407 VRF_BITMAP_FLAG (offset
));
411 vrf_bitmap_check (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
413 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
414 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
415 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
417 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
418 bm
->groups
[group
] == NULL
)
421 return CHECK_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
422 VRF_BITMAP_FLAG (offset
)) ? 1 : 0;
425 /* Initialize VRF module. */
429 struct vrf
*default_vrf
;
432 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__
);
434 /* The default VRF always exists. */
435 default_vrf
= vrf_get (VRF_DEFAULT
, VRF_DEFAULT_NAME
);
438 zlog_err ("vrf_init: failed to create the default VRF!");
442 /* Enable the default VRF. */
443 if (!vrf_enable (default_vrf
))
445 zlog_err ("vrf_init: failed to enable the default VRF!");
450 /* Terminate VRF module. */
457 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__
);
459 while ((vrf
= RB_ROOT (&vrfs_by_id
)) != NULL
)
461 while ((vrf
= RB_ROOT (&vrfs_by_name
)) != NULL
)
465 /* Create a socket for the VRF. */
467 vrf_socket (int domain
, int type
, int protocol
, vrf_id_t vrf_id
)
471 ret
= socket (domain
, type
, protocol
);
476 /* vrf CLI commands */
480 "Select a VRF to configure\n"
486 if ((sl
= strlen(argv
[0])) > VRF_NAMSIZ
)
488 vty_out (vty
, "%% VRF name %s is invalid: length exceeds "
490 argv
[0], VRF_NAMSIZ
, VTY_NEWLINE
);
494 vrfp
= vrf_get (VRF_UNKNOWN
, argv
[0]);
496 VTY_PUSH_CONTEXT_COMPAT (VRF_NODE
, vrfp
);
505 "Delete a pseudo VRF's configuration\n"
510 vrfp
= vrf_lookup_by_name (argv
[0]);
514 vty_out (vty
, "%% VRF %s does not exist%s", argv
[0], VTY_NEWLINE
);
518 if (CHECK_FLAG (vrfp
->status
, VRF_ACTIVE
))
520 vty_out (vty
, "%% Only inactive VRFs can be deleted%s",
531 * Debug CLI for vrf's
557 vrf_write_host (struct vty
*vty
)
560 vty_out (vty
, "debug vrf%s", VTY_NEWLINE
);
565 static struct cmd_node vrf_debug_node
=
573 vrf_install_commands (void)
575 install_node (&vrf_debug_node
, vrf_write_host
);
577 install_element (CONFIG_NODE
, &vrf_debug_cmd
);
578 install_element (ENABLE_NODE
, &vrf_debug_cmd
);
579 install_element (CONFIG_NODE
, &no_vrf_debug_cmd
);
580 install_element (ENABLE_NODE
, &no_vrf_debug_cmd
);